-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][Sema] Fixed Compound Literal is not Constant Expression #143852
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][Sema] Fixed Compound Literal is not Constant Expression #143852
Conversation
Added a check for a compound literal hiding inside a function. fixes llvm#87867
@llvm/pr-subscribers-clang Author: Vincent (Mr-Anyone) ChangesAdded 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:
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;
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM aside from a nit, thank you for working on this!
clang/lib/Sema/SemaExpr.cpp
Outdated
@@ -7219,6 +7219,17 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty, | |||
return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, InitExpr); | |||
} | |||
|
|||
static bool IsInsideFunction(Scope *S) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static bool IsInsideFunction(Scope *S) { | |
static bool IsContainedByFunctionScope(const Scope *S) { |
makes it more clear that we're checking whether the given scope is itself somewhere within a function scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AaronBallman it feels like it makes sense to sink this into Scope
just like isInObjCMethodScope()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can go either way. This is currently the first time we've needed this, so a static function makes sense. But if we need this a second time, then absolutely agreed it should be hoisted into Scope
. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do see people using this from time to time. I just moved this logic into Scope
.
✅ With the latest revision this PR passed the C/C++ code formatter. |
8dd64c3
to
cc509b9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@AaronBallman I don't have merge access. Could you please merge this for me? Thanks. |
Absolutely, thank you for letting me know. :-) |
…#143852) Added a check for a compound literal hiding inside a function. fixes llvm#87867
…#143852) Added a check for a compound literal hiding inside a function. fixes llvm#87867
Added a check for a compound literal hiding inside a function.
fixes #87867