https://github.com/Mr-Anyone updated https://github.com/llvm/llvm-project/pull/143852
>From 76a34f3e55eed586e63d21e7c45137cb33f94530 Mon Sep 17 00:00:00 2001 From: Vincent <l...@viceroygroup.ca> Date: Thu, 12 Jun 2025 16:03:58 +0800 Subject: [PATCH 1/2] [clang][Sema] Fixed Compound Literal is not Constant Expression Added a check for a compound literal hiding inside a function. fixes #87867 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaExpr.cpp | 12 ++++++++++++ clang/test/Sema/gh87867.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 clang/test/Sema/gh87867.c 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; +} >From 8dd64c3dcec9978937a464d98ed6632fe7845cc3 Mon Sep 17 00:00:00 2001 From: Vincent <l...@viceroygroup.ca> Date: Mon, 16 Jun 2025 21:56:06 +0800 Subject: [PATCH 2/2] Moved `IsInsideFunction` into `Scope` with a new name --- clang/include/clang/Sema/Scope.h | 11 +++++++++++ clang/lib/Sema/SemaExpr.cpp | 13 +------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h index ad12a3d73413b..02ace2d7ef20c 100644 --- a/clang/include/clang/Sema/Scope.h +++ b/clang/include/clang/Sema/Scope.h @@ -427,6 +427,17 @@ class Scope { return false; } + /// isInObjcMethodScope - Return true if this scope is, or is contained, in an + /// C function body. + bool isInCFunctionScope() const { + for (const Scope *S = this; S; S = S->getParent()) { + if (S->isFunctionScope()) + return true; + } + + return false; + } + /// isInObjcMethodScope - Return true if this scope is, or is contained in, an /// Objective-C method body. Note that this method is not constant time. bool isInObjcMethodScope() const { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 5468d6573b4bb..710f71650e385 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7219,17 +7219,6 @@ 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) { @@ -7292,7 +7281,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->isInCFunctionScope() && (!S || !S->isFunctionPrototypeScope()); // In C, compound literals are l-values for some reason. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits