Skip to content

Commit 977d8a4

Browse files
authored
[clang][Sema] Fixed Compound Literal is not Constant Expression (llvm#143852)
Added a check for a compound literal hiding inside a function. fixes llvm#87867
1 parent 76ea1db commit 977d8a4

File tree

4 files changed

+47
-0
lines changed

4 files changed

+47
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,8 @@ Bug Fixes in This Version
692692
``#include`` directive. (#GH138094)
693693
- Fixed a crash during constant evaluation involving invalid lambda captures
694694
(#GH138832)
695+
- Fixed compound literal is not constant expression inside initializer list
696+
(#GH87867)
695697
- Fixed a crash when instantiating an invalid dependent friend template specialization.
696698
(#GH139052)
697699
- Fixed a crash with an invalid member function parameter list with a default

clang/include/clang/Sema/Scope.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,17 @@ class Scope {
427427
return false;
428428
}
429429

430+
/// isInObjcMethodScope - Return true if this scope is, or is contained, in an
431+
/// C function body.
432+
bool isInCFunctionScope() const {
433+
for (const Scope *S = this; S; S = S->getParent()) {
434+
if (S->isFunctionScope())
435+
return true;
436+
}
437+
438+
return false;
439+
}
440+
430441
/// isInObjcMethodScope - Return true if this scope is, or is contained in, an
431442
/// Objective-C method body. Note that this method is not constant time.
432443
bool isInObjcMethodScope() const {

clang/lib/Sema/SemaExpr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7176,6 +7176,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
71767176
// void func(char *para[(int [1]){ 0 }[0]);
71777177
const Scope *S = getCurScope();
71787178
bool IsFileScope = !CurContext->isFunctionOrMethod() &&
7179+
!S->isInCFunctionScope() &&
71797180
(!S || !S->isFunctionPrototypeScope());
71807181

71817182
// 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)