Skip to content

Commit 86029ca

Browse files
committed
[clang] Compound Literal Statement Constant Expression Assertion Fix
Compound literals initializer-list should be a constant expression if it is defined outside the body of a function. Emit error instead of falling through tripping assertion error. fixes #139160
1 parent 76dba2e commit 86029ca

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

clang/lib/Sema/SemaExpr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7245,6 +7245,17 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
72457245
if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr))
72467246
for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) {
72477247
Expr *Init = ILE->getInit(i);
7248+
// C99 6.5.2.5
7249+
// "If the compound literal occurs outside the body of a function, the
7250+
// initializer list shall consist of constant expressions."
7251+
if (!Init->isTypeDependent() && !Init->isValueDependent() &&
7252+
!Init->getType()->isDependentType())
7253+
if (!Init->isConstantInitializer(Context, false)) {
7254+
Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
7255+
<< Init->getSourceBitField();
7256+
return ExprError();
7257+
}
7258+
72487259
ILE->setInit(i, ConstantExpr::Create(Context, Init));
72497260
}
72507261

clang/test/SemaCXX/cxx2a-consteval.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,3 +1300,25 @@ void foo() {
13001300
}
13011301

13021302
}
1303+
1304+
// https://github.com/llvm/llvm-project/issues/139160
1305+
namespace GH139160{
1306+
// original test case taken from Github
1307+
struct A {int x[1]; };
1308+
A f(); // expected-note {{declared here}}
1309+
typedef int *t[];
1310+
consteval int* f(int* x) { return x; }
1311+
1312+
int ** x = (t){f(f().x)}; // expected-error {{call to consteval function 'GH139160::f' is not a constant expression}}
1313+
// expected-note@-1 {{non-constexpr function 'f' cannot be used in a constant expression}}
1314+
// expected-error@-2 {{initializer element is not a compile-time constant}}
1315+
1316+
struct B {int value, value_two;};
1317+
B make_struct() {return {10, 20};} // expected-note {{declared here}}
1318+
consteval int get_value(B container) {return container.value;}
1319+
B result = (B){10, get_value(make_struct())}; // expected-error {{initializer element is not a compile-time constant}}
1320+
// expected-error@-1 {{call to consteval function 'GH139160::get_value' is not a constant expression}}
1321+
// expected-note@-2 {{non-constexpr function 'make_struct' cannot be used in a constant expression}}
1322+
};
1323+
1324+

0 commit comments

Comments
 (0)