https://github.com/Mr-Anyone updated 
https://github.com/llvm/llvm-project/pull/139479

>From 86029ca424ddee771b95182b53d5bbdfd7fd049d Mon Sep 17 00:00:00 2001
From: Vincent <l...@viceroygroup.ca>
Date: Sun, 11 May 2025 19:01:34 -0400
Subject: [PATCH 1/3] [clang] Compound Literal Statement Constant Expression
 Assertion Fix

Compound literals initializer-list should be a constant expression if it is 
defined outside the body of a function.

Emit error instead of falling through tripping assertion error.

fixes #139160
---
 clang/lib/Sema/SemaExpr.cpp            | 11 +++++++++++
 clang/test/SemaCXX/cxx2a-consteval.cpp | 22 ++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2c81f7c583eb6..3d70bc62dd2cf 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7245,6 +7245,17 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, 
TypeSourceInfo *TInfo,
     if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr))
       for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) {
         Expr *Init = ILE->getInit(i);
+        // C99 6.5.2.5
+        //  "If the compound literal occurs outside the body of a function, the
+        //  initializer list shall consist of constant expressions."
+        if (!Init->isTypeDependent() && !Init->isValueDependent() &&
+            !Init->getType()->isDependentType())
+          if (!Init->isConstantInitializer(Context, false)) {
+            Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
+                << Init->getSourceBitField();
+            return ExprError();
+          }
+
         ILE->setInit(i, ConstantExpr::Create(Context, Init));
       }
 
diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp 
b/clang/test/SemaCXX/cxx2a-consteval.cpp
index d9d144cafdbcc..d9932e4dd8241 100644
--- a/clang/test/SemaCXX/cxx2a-consteval.cpp
+++ b/clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -1300,3 +1300,25 @@ void foo() {
 }
 
 }
+
+// https://github.com/llvm/llvm-project/issues/139160
+namespace GH139160{
+  // original test case taken from Github
+  struct A {int x[1]; }; 
+  A f(); // expected-note {{declared here}}
+  typedef int *t[];
+  consteval int* f(int* x) { return x; }
+
+  int ** x = (t){f(f().x)}; // expected-error    {{call to consteval function 
'GH139160::f' is not a constant expression}}
+                            // expected-note@-1  {{non-constexpr function 'f' 
cannot be used in a constant expression}}
+                            // expected-error@-2 {{initializer element is not 
a compile-time constant}} 
+
+  struct B {int value, value_two;};
+  B make_struct() {return {10, 20};} // expected-note {{declared here}}
+  consteval int get_value(B container) {return container.value;}
+  B result = (B){10, get_value(make_struct())}; // expected-error 
{{initializer element is not a compile-time constant}} 
+                                                // expected-error@-1 {{call to 
consteval function 'GH139160::get_value' is not a constant expression}}
+                                                // expected-note@-2  
{{non-constexpr function 'make_struct' cannot be used in a constant expression}}
+};
+
+

>From b969ec109b28521af51f5d3a3ed71eb6f050c955 Mon Sep 17 00:00:00 2001
From: Vincent <l...@viceroygroup.ca>
Date: Mon, 12 May 2025 08:10:06 -0400
Subject: [PATCH 2/3] Added Release Notes and moved comments and minor nits.

---
 clang/docs/ReleaseNotes.rst | 1 +
 clang/lib/Sema/SemaExpr.cpp | 8 ++++----
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 44c38396c764f..82d2e60ccc077 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -589,6 +589,7 @@ Bug Fixes in This Version
 - Fixed a crash with an invalid member function parameter list with a default
   argument which contains a pragma. (#GH113722)
 - Fixed assertion failures when generating name lookup table in modules. 
(#GH61065, #GH134739)
+- Fixed an assertion failure in constant compound literal statements. 
(#GH139160)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3d70bc62dd2cf..2d59999c7e396 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7241,16 +7241,16 @@ Sema::BuildCompoundLiteralExpr(SourceLocation 
LParenLoc, TypeSourceInfo *TInfo,
           ? VK_PRValue
           : VK_LValue;
 
+  // C99 6.5.2.5
+  //  "If the compound literal occurs outside the body of a function, the
+  //  initializer list shall consist of constant expressions."
   if (IsFileScope)
     if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr))
       for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) {
         Expr *Init = ILE->getInit(i);
-        // C99 6.5.2.5
-        //  "If the compound literal occurs outside the body of a function, the
-        //  initializer list shall consist of constant expressions."
         if (!Init->isTypeDependent() && !Init->isValueDependent() &&
             !Init->getType()->isDependentType())
-          if (!Init->isConstantInitializer(Context, false)) {
+          if (!Init->isConstantInitializer(Context, /*IsForRef=*/false)) {
             Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
                 << Init->getSourceBitField();
             return ExprError();

>From 80b072e6343b6469e9f4f66e3fb99184b263d416 Mon Sep 17 00:00:00 2001
From: Vincent <l...@viceroygroup.ca>
Date: Wed, 14 May 2025 14:04:37 -0400
Subject: [PATCH 3/3] Remove Redundant Check

---
 clang/lib/Sema/SemaExpr.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2d59999c7e396..637c3c927fd6f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7248,8 +7248,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, 
TypeSourceInfo *TInfo,
     if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr))
       for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) {
         Expr *Init = ILE->getInit(i);
-        if (!Init->isTypeDependent() && !Init->isValueDependent() &&
-            !Init->getType()->isDependentType())
+        if (!Init->isTypeDependent() && !Init->isValueDependent())
           if (!Init->isConstantInitializer(Context, /*IsForRef=*/false)) {
             Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
                 << Init->getSourceBitField();

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

Reply via email to