1 From 2ba4e83e61617daee70f98fcdd76cb8bc3d6ac38 Mon Sep 17 00:00:00 2001
2 From: serge-sans-paille <sguelton@redhat.com>
3 Date: Sat, 18 Jun 2022 13:48:41 +0200
4 Subject: [PATCH] [clang] Enforce instantiation of constexpr template functions
5 during non-constexpr evaluation
7 Otherwise these functions are not instantiated and we end up with an undefined
12 Differential Revision: https://reviews.llvm.org/D128119
14 (cherry picked from commit da6a14b91ad999327b41a9040577273591e4ad1d)
16 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 +++--
17 .../CodeGenCXX/constexpr-late-instantiation.cpp | 17 +++++++++++++++++
18 .../SemaCXX/constexpr-late-instantiation.cpp | 15 +++++++++++++++
19 3 files changed, 35 insertions(+), 2 deletions(-)
20 create mode 100644 clang/test/CodeGenCXX/constexpr-late-instantiation.cpp
21 create mode 100644 clang/test/SemaCXX/constexpr-late-instantiation.cpp
23 diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
24 index 467372c71496..293782822e83 100644
25 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
26 +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
27 @@ -4826,7 +4826,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
28 /*Complain*/DefinitionRequired)) {
29 if (DefinitionRequired)
30 Function->setInvalidDecl();
31 - else if (TSK == TSK_ExplicitInstantiationDefinition) {
32 + else if (TSK == TSK_ExplicitInstantiationDefinition ||
33 + (Function->isConstexpr() && !Recursive)) {
34 // Try again at the end of the translation unit (at which point a
35 // definition will be required).
37 @@ -4841,7 +4842,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
38 Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
39 if (getLangOpts().CPlusPlus11)
40 Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
46 diff --git a/clang/test/CodeGenCXX/constexpr-late-instantiation.cpp b/clang/test/CodeGenCXX/constexpr-late-instantiation.cpp
48 index 000000000000..1c8eef73f2dd
50 +++ b/clang/test/CodeGenCXX/constexpr-late-instantiation.cpp
52 +// Make sure foo is instantiated and we don't get a link error
53 +// RUN: %clang_cc1 -S -emit-llvm -triple %itanium_abi_triple %s -o- | FileCheck %s
55 +template <typename T>
56 +constexpr T foo(T a);
58 +// CHECK-LABEL: define {{.*}} @main
60 + // CHECK: call {{.*}} @_Z3fooIiET_S0_
61 + int k = foo<int>(5);
65 +template <typename T>
66 +constexpr T foo(T a) {
69 diff --git a/clang/test/SemaCXX/constexpr-late-instantiation.cpp b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
71 index 000000000000..ec8e071217c1
73 +++ b/clang/test/SemaCXX/constexpr-late-instantiation.cpp
75 +// RUN: %clang_cc1 %s -fsyntax-only -verify
77 +template <typename T>
78 +constexpr T foo(T a); // expected-note {{declared here}}
81 + int k = foo<int>(5); // Ok
82 + constexpr int j = // expected-error {{constexpr variable 'j' must be initialized by a constant expression}}
83 + foo<int>(5); // expected-note {{undefined function 'foo<int>' cannot be used in a constant expression}}
86 +template <typename T>
87 +constexpr T foo(T a) {