Skip to content

Commit 56e27a6

Browse files
author
git apple-llvm automerger
committed
Merge commit '9c33faf8628a' from llvm.org/main into next
2 parents 3642568 + 9c33faf commit 56e27a6

File tree

4 files changed

+58
-18
lines changed

4 files changed

+58
-18
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,7 @@ Bug Fixes to C++ Support
746746
- Fixed bug in constant evaluation that would allow using the value of a
747747
reference in its own initializer in C++23 mode (#GH131330).
748748
- Clang could incorrectly instantiate functions in discarded contexts (#GH140449)
749+
- Fix instantiation of default-initialized variable template specialization. (#GH140632) (#GH140622)
749750

750751
Bug Fixes to AST Handling
751752
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6069,22 +6069,20 @@ void Sema::InstantiateVariableInitializer(
60696069
else if (OldVar->isInline())
60706070
Var->setImplicitlyInline();
60716071

6072-
if (OldVar->getInit()) {
6073-
EnterExpressionEvaluationContext Evaluated(
6074-
*this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var);
6072+
ContextRAII SwitchContext(*this, Var->getDeclContext());
60756073

6076-
currentEvaluationContext().InLifetimeExtendingContext =
6077-
parentEvaluationContext().InLifetimeExtendingContext;
6078-
currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
6079-
parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
6080-
// Instantiate the initializer.
6081-
ExprResult Init;
6074+
EnterExpressionEvaluationContext Evaluated(
6075+
*this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var);
6076+
currentEvaluationContext().InLifetimeExtendingContext =
6077+
parentEvaluationContext().InLifetimeExtendingContext;
6078+
currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
6079+
parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
60826080

6083-
{
6084-
ContextRAII SwitchContext(*this, Var->getDeclContext());
6085-
Init = SubstInitializer(OldVar->getInit(), TemplateArgs,
6086-
OldVar->getInitStyle() == VarDecl::CallInit);
6087-
}
6081+
if (OldVar->getInit()) {
6082+
// Instantiate the initializer.
6083+
ExprResult Init =
6084+
SubstInitializer(OldVar->getInit(), TemplateArgs,
6085+
OldVar->getInitStyle() == VarDecl::CallInit);
60886086

60896087
if (!Init.isInvalid()) {
60906088
Expr *InitExpr = Init.get();

clang/test/CodeGenCXX/cxx1y-variable-template.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
1+
// RUN: %clang_cc1 -std=c++1y -Wno-unused-value -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
22

33
// Check that we keep the 'extern' when we instantiate the definition of this
44
// variable template specialization.
@@ -18,6 +18,16 @@ int init_arr();
1818
template<typename T> template<typename U> template<typename V> int Outer<T>::Inner<U>::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
1919
int *p = Outer<char[100]>::Inner<char[20]>::arr<char[3]>;
2020

21+
//CHECK: @_ZN8GH1406221gIiEE = linkonce_odr constant %"struct.GH140622::S" zeroinitializer
22+
namespace GH140622 {
23+
template <typename> struct S {};
24+
template <typename T> constexpr S<T> g;
25+
void test() {
26+
constexpr auto x = 42;
27+
x, g<int>;
28+
}
29+
}
30+
2131
namespace PR35456 {
2232
// CHECK: @_ZN7PR354561nILi0EEE = linkonce_odr global i32 0
2333
template<int> int n;

clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// RUN: %clang_cc1 -std=c++98 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11
2-
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s
3-
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
1+
// RUN: %clang_cc1 -std=c++98 -verify -fsyntax-only -Wno-unused-value -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11
2+
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-unused-value -Wno-c++1y-extensions %s
3+
// RUN: %clang_cc1 -std=c++17 -verify -fsyntax-only -Wno-unused-value %s
4+
// RUN: %clang_cc1 -std=c++2c -verify -fsyntax-only -Wno-unused-value %s
5+
46

57
#ifdef PRECXX11
68
#define CONST const
@@ -510,3 +512,32 @@ template <> auto b<0, 0, 0> = b<0, 0, 0>; // expected-error {{variable template
510512
}
511513

512514
#endif
515+
516+
#if __cplusplus > 201702L
517+
namespace GH140622 {
518+
template <typename> struct S {};
519+
520+
struct Outer {
521+
template <typename T>
522+
static constexpr S<T> g;
523+
};
524+
525+
template <typename T>
526+
struct OuterTpl {
527+
static constexpr S<T> f;
528+
template <typename U>
529+
static constexpr S<U> g;
530+
};
531+
532+
template <typename T>
533+
constexpr S<T> g;
534+
535+
void test() {
536+
constexpr auto x = 42;
537+
x, g<int>,
538+
Outer::g<int>,
539+
OuterTpl<int>::f,
540+
OuterTpl<int>::g<int>;
541+
}
542+
}
543+
#endif

0 commit comments

Comments
 (0)