https://github.com/cor3ntin updated 
https://github.com/llvm/llvm-project/pull/140699

>From 2b62227227310785e74c71961e36cd0ab7b799d1 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinja...@gmail.com>
Date: Tue, 20 May 2025 11:44:59 +0200
Subject: [PATCH 1/2] [Clang] Use correct evaluation contexts when
 instantiating a var without initializer

The evaluation context was improperly set up, such that we were
trying to setup cleanups for a global var at the point of use,
which lead to incorrect diagnostics about the variable not being
capturable.

Fixes #140632
Fixes #140622
---
 clang/docs/ReleaseNotes.rst                   |  1 +
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  | 26 ++++++-------
 .../CodeGenCXX/cxx1y-variable-template.cpp    | 12 +++++-
 .../cxx1y-variable-templates_top_level.cpp    | 37 +++++++++++++++++--
 4 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f04cb7b91788c..8e6cf62e11752 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -746,6 +746,7 @@ Bug Fixes to C++ Support
 - Fixed bug in constant evaluation that would allow using the value of a
   reference in its own initializer in C++23 mode (#GH131330).
 - Clang could incorrectly instantiate functions in discarded contexts 
(#GH140449)
+- Fix instantiation of default-initialized variable template specialization. 
(#GH140632) (#GH140622)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b12085c6f6935..d1f313e9cb487 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6069,22 +6069,20 @@ void Sema::InstantiateVariableInitializer(
   else if (OldVar->isInline())
     Var->setImplicitlyInline();
 
-  if (OldVar->getInit()) {
-    EnterExpressionEvaluationContext Evaluated(
-        *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var);
+  ContextRAII SwitchContext(*this, Var->getDeclContext());
 
-    currentEvaluationContext().InLifetimeExtendingContext =
-        parentEvaluationContext().InLifetimeExtendingContext;
-    currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
-        parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
-    // Instantiate the initializer.
-    ExprResult Init;
+  EnterExpressionEvaluationContext Evaluated(
+      *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var);
+  currentEvaluationContext().InLifetimeExtendingContext =
+      parentEvaluationContext().InLifetimeExtendingContext;
+  currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
+      parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
 
-    {
-      ContextRAII SwitchContext(*this, Var->getDeclContext());
-      Init = SubstInitializer(OldVar->getInit(), TemplateArgs,
-                              OldVar->getInitStyle() == VarDecl::CallInit);
-    }
+  if (OldVar->getInit()) {
+    // Instantiate the initializer.
+    ExprResult Init =
+        SubstInitializer(OldVar->getInit(), TemplateArgs,
+                         OldVar->getInitStyle() == VarDecl::CallInit);
 
     if (!Init.isInvalid()) {
       Expr *InitExpr = Init.get();
diff --git a/clang/test/CodeGenCXX/cxx1y-variable-template.cpp 
b/clang/test/CodeGenCXX/cxx1y-variable-template.cpp
index 7c0351881f198..885107ee95d88 100644
--- a/clang/test/CodeGenCXX/cxx1y-variable-template.cpp
+++ b/clang/test/CodeGenCXX/cxx1y-variable-template.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -std=c++1y -Wno-unused-value -triple x86_64-linux-gnu 
-emit-llvm -o - %s | FileCheck %s
 
 // Check that we keep the 'extern' when we instantiate the definition of this
 // variable template specialization.
@@ -18,6 +18,16 @@ int init_arr();
 template<typename T> template<typename U> template<typename V> int 
Outer<T>::Inner<U>::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
 int *p = Outer<char[100]>::Inner<char[20]>::arr<char[3]>;
 
+//CHECK : @_ZN8GH1406221gIiEE = linkonce_odr constant %"struct.GH140622::S" 
zeroinitializer
+namespace GH140622 {
+template <typename> struct S {};
+template <typename T> constexpr S<T> g;
+void test() {
+    constexpr auto x = 42;
+    x, g<int>;
+}
+}
+
 namespace PR35456 {
 // CHECK: @_ZN7PR354561nILi0EEE = linkonce_odr global i32 0
 template<int> int n;
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp 
b/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
index 1fe0ce9aabf29..aada11dd5f9be 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -std=c++98 -verify -fsyntax-only -Wno-c++11-extensions 
-Wno-c++1y-extensions %s -DPRECXX11
-// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s
-// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
+// RUN: %clang_cc1 -std=c++98 -verify -fsyntax-only -Wno-unused-value 
-Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11
+// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-unused-value 
-Wno-c++1y-extensions %s
+// RUN: %clang_cc1 -std=c++17 -verify -fsyntax-only -Wno-unused-value %s
+// RUN: %clang_cc1 -std=c++2c -verify -fsyntax-only -Wno-unused-value %s
+
 
 #ifdef PRECXX11
   #define CONST const
@@ -510,3 +512,32 @@ template <> auto b<0, 0, 0> = b<0, 0, 0>; // 
expected-error {{variable template
 }
 
 #endif
+
+#if __cplusplus > 201702L
+namespace GH140622 {
+template <typename> struct S {};
+
+struct Outer {
+    template <typename T>
+    static constexpr S<T> g;
+};
+
+template <typename T>
+struct OuterTpl {
+    static constexpr S<T> f;
+    template <typename U>
+    static constexpr S<U> g;
+};
+
+template <typename T>
+constexpr S<T> g;
+
+void test() {
+    constexpr auto x = 42;
+    x, g<int>,
+    Outer::g<int>,
+    OuterTpl<int>::f,
+    OuterTpl<int>::g<int>;
+}
+}
+#endif

>From f771a802dde44ff4d096dc6dfd6bb97748356c64 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinja...@gmail.com>
Date: Tue, 20 May 2025 14:04:02 +0200
Subject: [PATCH 2/2] remove space

---
 clang/test/CodeGenCXX/cxx1y-variable-template.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/CodeGenCXX/cxx1y-variable-template.cpp 
b/clang/test/CodeGenCXX/cxx1y-variable-template.cpp
index 885107ee95d88..329b6c0cb86ae 100644
--- a/clang/test/CodeGenCXX/cxx1y-variable-template.cpp
+++ b/clang/test/CodeGenCXX/cxx1y-variable-template.cpp
@@ -18,7 +18,7 @@ int init_arr();
 template<typename T> template<typename U> template<typename V> int 
Outer<T>::Inner<U>::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
 int *p = Outer<char[100]>::Inner<char[20]>::arr<char[3]>;
 
-//CHECK : @_ZN8GH1406221gIiEE = linkonce_odr constant %"struct.GH140622::S" 
zeroinitializer
+//CHECK: @_ZN8GH1406221gIiEE = linkonce_odr constant %"struct.GH140622::S" 
zeroinitializer
 namespace GH140622 {
 template <typename> struct S {};
 template <typename T> constexpr S<T> g;

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to