Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions clang/include/clang/Sema/Scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7281,6 +7281,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
// void func(char *para[(int [1]){ 0 }[0]);
const Scope *S = getCurScope();
bool IsFileScope = !CurContext->isFunctionOrMethod() &&
!S->isInCFunctionScope() &&
(!S || !S->isFunctionPrototypeScope());

// In C, compound literals are l-values for some reason.
Expand Down
33 changes: 33 additions & 0 deletions clang/test/Sema/gh87867.c
Original file line number Diff line number Diff line change
@@ -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;
}
Loading