Skip to content

Commit 76a34f3

Browse files
committed
[clang][Sema] Fixed Compound Literal is not Constant Expression
Added a check for a compound literal hiding inside a function. fixes #87867
1 parent 9d491bc commit 76a34f3

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,8 @@ Bug Fixes in This Version
680680
``#include`` directive. (#GH138094)
681681
- Fixed a crash during constant evaluation involving invalid lambda captures
682682
(#GH138832)
683+
- Fixed compound literal is not constant expression inside initializer list
684+
(#GH87867)
683685
- Fixed a crash when instantiating an invalid dependent friend template specialization.
684686
(#GH139052)
685687
- Fixed a crash with an invalid member function parameter list with a default

clang/lib/Sema/SemaExpr.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7219,6 +7219,17 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
72197219
return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, InitExpr);
72207220
}
72217221

7222+
static bool IsInsideFunction(Scope *S) {
7223+
while (S) {
7224+
if (S->isFunctionScope())
7225+
return true;
7226+
7227+
S = S->getParent();
7228+
}
7229+
7230+
return false;
7231+
}
7232+
72227233
ExprResult
72237234
Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
72247235
SourceLocation RParenLoc, Expr *LiteralExpr) {
@@ -7281,6 +7292,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
72817292
// void func(char *para[(int [1]){ 0 }[0]);
72827293
const Scope *S = getCurScope();
72837294
bool IsFileScope = !CurContext->isFunctionOrMethod() &&
7295+
!IsInsideFunction(getCurScope()) &&
72847296
(!S || !S->isFunctionPrototypeScope());
72857297

72867298
// In C, compound literals are l-values for some reason.

clang/test/Sema/gh87867.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 %s
2+
3+
// Compound literal doesn't need a constant expression inside a initializer-list if it is already inside a function
4+
// see: https://github.com/llvm/llvm-project/issues/87867
5+
int foo(int *a, int b) {
6+
return 0;
7+
}
8+
9+
int x;
10+
struct{int t;} a = (struct {
11+
typeof(foo(&(struct { int t; }){.t = x}.t, 0)) t; // expected-error {{initializer element is not a compile-time constant}}
12+
}){0};
13+
14+
void inside_a_func(){
15+
int x;
16+
(void)(struct {
17+
typeof(foo(&(struct { int t; }){.t = x}.t, 0)) t;
18+
}){0};
19+
}
20+
21+
// see: https://github.com/llvm/llvm-project/issues/143613
22+
#define bitcast(type, value) \
23+
(((union{ typeof(value) src; type dst; }){ (value) }).dst)
24+
25+
double placeholder = 10.0;
26+
double bar = bitcast(double, placeholder); // expected-error {{initializer element is not a compile-time constant}}
27+
28+
int main(void)
29+
{
30+
int foo = 4;
31+
foo = bitcast(int, bitcast(double, foo));
32+
return 0;
33+
}

0 commit comments

Comments
 (0)