https://github.com/Mr-Anyone created https://github.com/llvm/llvm-project/pull/143852
Added a check for a compound literal hiding inside a function. fixes #87867 >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] [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; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits