[clang] [clang][Sema] Fixed Compound Literal is not Constant Expression (PR #143852)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 12 01:21:48 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Vincent (Mr-Anyone)
<details>
<summary>Changes</summary>
Added a check for a compound literal hiding inside a function.
fixes #<!-- -->87867
---
Full diff: https://github.com/llvm/llvm-project/pull/143852.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+2)
- (modified) clang/lib/Sema/SemaExpr.cpp (+12)
- (added) clang/test/Sema/gh87867.c (+33)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b42d5f8425af6..df1963f19e35f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -680,6 +680,8 @@ Bug Fixes in This Version
``#include`` directive. (#GH138094)
- Fixed a crash during constant evaluation involving invalid lambda captures
(#GH138832)
+- Fixed compound literal is not constant expression inside initializer list
+ (#GH87867)
- Fixed a crash when instantiating an invalid dependent friend template specialization.
(#GH139052)
- Fixed a crash with an invalid member function parameter list with a default
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c7abbbd6993de..5468d6573b4bb 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7219,6 +7219,17 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, InitExpr);
}
+static bool IsInsideFunction(Scope *S) {
+ while (S) {
+ if (S->isFunctionScope())
+ return true;
+
+ S = S->getParent();
+ }
+
+ return false;
+}
+
ExprResult
Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
SourceLocation RParenLoc, Expr *LiteralExpr) {
@@ -7281,6 +7292,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
// void func(char *para[(int [1]){ 0 }[0]);
const Scope *S = getCurScope();
bool IsFileScope = !CurContext->isFunctionOrMethod() &&
+ !IsInsideFunction(getCurScope()) &&
(!S || !S->isFunctionPrototypeScope());
// In C, compound literals are l-values for some reason.
diff --git a/clang/test/Sema/gh87867.c b/clang/test/Sema/gh87867.c
new file mode 100644
index 0000000000000..0568c734424ca
--- /dev/null
+++ b/clang/test/Sema/gh87867.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 %s
+
+// Compound literal doesn't need a constant expression inside a initializer-list if it is already inside a function
+// see: https://github.com/llvm/llvm-project/issues/87867
+int foo(int *a, int b) {
+ return 0;
+}
+
+int x;
+struct{int t;} a = (struct {
+ typeof(foo(&(struct { int t; }){.t = x}.t, 0)) t; // expected-error {{initializer element is not a compile-time constant}}
+}){0};
+
+void inside_a_func(){
+ int x;
+ (void)(struct {
+ typeof(foo(&(struct { int t; }){.t = x}.t, 0)) t;
+ }){0};
+}
+
+// see: https://github.com/llvm/llvm-project/issues/143613
+#define bitcast(type, value) \
+ (((union{ typeof(value) src; type dst; }){ (value) }).dst)
+
+double placeholder = 10.0;
+double bar = bitcast(double, placeholder); // expected-error {{initializer element is not a compile-time constant}}
+
+int main(void)
+{
+ int foo = 4;
+ foo = bitcast(int, bitcast(double, foo));
+ return 0;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/143852
More information about the cfe-commits
mailing list