[clang] [Clang] Use correct evaluation contexts when instantiating a var without initializer (PR #140699)
https://github.com/shafik commented: It would also be nice to get a reduction for: https://github.com/llvm/llvm-project/issues/140632 and see if we can add a test for that if it looks significantly different from the other cases. https://github.com/llvm/llvm-project/pull/140699 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Use correct evaluation contexts when instantiating a var without initializer (PR #140699)
@@ -18,6 +18,16 @@ int init_arr();
template template template int
Outer::Inner::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
int *p = Outer::Inner::arr;
+//CHECK: @_ZN8GH1406221gIiEE = linkonce_odr constant %"struct.GH140622::S"
zeroinitializer
+namespace GH140622 {
+template struct S {};
+template constexpr S g;
+void test() {
+constexpr auto x = 42;
shafik wrote:
As I pointed out here:
https://github.com/llvm/llvm-project/issues/140622#issuecomment-2892633775
this also happens when the local is *const*, so it is worth testing that case
and the non const/constexpr case.
https://github.com/llvm/llvm-project/pull/140699
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Use correct evaluation contexts when instantiating a var without initializer (PR #140699)
https://github.com/shafik edited https://github.com/llvm/llvm-project/pull/140699 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Use correct evaluation contexts when instantiating a var without initializer (PR #140699)
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
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 template template int
Outer::Inner::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
int *p = Outer::Inner::arr;
+//CHECK : @_ZN8GH1406221gIiEE = linkonce_odr constant %"struct.GH140622::S"
zeroinitializer
+namespace GH140622 {
+template struct S {};
+template constexpr S g;
+void test() {
+constexpr auto x = 42;
+x, g;
+}
+}
+
namespace PR35456 {
// CHECK: @_ZN7PR354561nILi0EEE = linkonce_odr global i32 0
template 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
[clang] [Clang] Use correct evaluation contexts when instantiating a var without initializer (PR #140699)
https://github.com/cor3ntin closed https://github.com/llvm/llvm-project/pull/140699 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Use correct evaluation contexts when instantiating a var without initializer (PR #140699)
llvmbot wrote:
@llvm/pr-subscribers-clang
Author: cor3ntin (cor3ntin)
Changes
The evaluation context was improperly set up, such that we were trying to set
up cleanups for a global variable at the point of use, which led to incorrect
diagnostics about the variable not being capturable.
Fixes #140632
Fixes #140622
---
Full diff: https://github.com/llvm/llvm-project/pull/140699.diff
4 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+1)
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+12-14)
- (modified) clang/test/CodeGenCXX/cxx1y-variable-template.cpp (+11-1)
- (modified) clang/test/SemaCXX/cxx1y-variable-templates_top_level.cpp (+34-3)
``diff
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 template template int
Outer::Inner::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
int *p = Outer::Inner::arr;
+//CHECK : @_ZN8GH1406221gIiEE = linkonce_odr constant %"struct.GH140622::S"
zeroinitializer
+namespace GH140622 {
+template struct S {};
+template constexpr S g;
+void test() {
+constexpr auto x = 42;
+x, g;
+}
+}
+
namespace PR35456 {
// CHECK: @_ZN7PR354561nILi0EEE = linkonce_odr global i32 0
template 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-exten
[clang] [Clang] Use correct evaluation contexts when instantiating a var without initializer (PR #140699)
https://github.com/cor3ntin created
https://github.com/llvm/llvm-project/pull/140699
The evaluation context was improperly set up, such that we were trying to set
up cleanups for a global variable at the point of use, which led to incorrect
diagnostics about the variable not being capturable.
Fixes #140632
Fixes #140622
>From 2b62227227310785e74c71961e36cd0ab7b799d1 Mon Sep 17 00:00:00 2001
From: Corentin Jabot
Date: Tue, 20 May 2025 11:44:59 +0200
Subject: [PATCH] [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 template template int
Outer::Inner::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
int *p = Outer::Inner::arr;
+//CHECK : @_ZN8GH1406221gIiEE = linkonce_odr constant %"struct.GH140622::S"
zeroinitializer
+namespace GH140622 {
+template struct S {};
+template constexpr S g;
+void test() {
+constexpr auto x = 42;
+x, g;
+}
+}
+
namespace PR35456 {
// CHECK: @_ZN7PR354561nILi0EEE = linkonce_odr global i32 0
template 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++1
