llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Vincent (Mr-Anyone) <details> <summary>Changes</summary> 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 --- Full diff: https://github.com/llvm/llvm-project/pull/139479.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaExpr.cpp (+11) - (modified) clang/test/SemaCXX/cxx2a-consteval.cpp (+22) ``````````diff diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index deb8d2edfc5c9..e06b6fc233fcc 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7220,6 +7220,17 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr)) for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) { Expr *Init = ILE->getInit(i); + // C99 6.5.2.5 + // "If the compound literal occurs outside the body of a function, the + // initializer list shall consist of constant expressions." + if (!Init->isTypeDependent() && !Init->isValueDependent() && + !Init->getType()->isDependentType()) + if (!Init->isConstantInitializer(Context, false)) { + Diag(Init->getExprLoc(), diag::err_init_element_not_constant) + << Init->getSourceBitField(); + return ExprError(); + } + ILE->setInit(i, ConstantExpr::Create(Context, Init)); } diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index d9d144cafdbcc..d9932e4dd8241 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -1300,3 +1300,25 @@ void foo() { } } + +// https://github.com/llvm/llvm-project/issues/139160 +namespace GH139160{ + // original test case taken from Github + struct A {int x[1]; }; + A f(); // expected-note {{declared here}} + typedef int *t[]; + consteval int* f(int* x) { return x; } + + int ** x = (t){f(f().x)}; // expected-error {{call to consteval function 'GH139160::f' is not a constant expression}} + // expected-note@-1 {{non-constexpr function 'f' cannot be used in a constant expression}} + // expected-error@-2 {{initializer element is not a compile-time constant}} + + struct B {int value, value_two;}; + B make_struct() {return {10, 20};} // expected-note {{declared here}} + consteval int get_value(B container) {return container.value;} + B result = (B){10, get_value(make_struct())}; // expected-error {{initializer element is not a compile-time constant}} + // expected-error@-1 {{call to consteval function 'GH139160::get_value' is not a constant expression}} + // expected-note@-2 {{non-constexpr function 'make_struct' cannot be used in a constant expression}} +}; + + `````````` </details> https://github.com/llvm/llvm-project/pull/139479 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits