https://github.com/AaronBallman updated https://github.com/llvm/llvm-project/pull/139479
>From 86029ca424ddee771b95182b53d5bbdfd7fd049d Mon Sep 17 00:00:00 2001 From: Vincent <l...@viceroygroup.ca> Date: Sun, 11 May 2025 19:01:34 -0400 Subject: [PATCH 1/4] [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 --- clang/lib/Sema/SemaExpr.cpp | 11 +++++++++++ clang/test/SemaCXX/cxx2a-consteval.cpp | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2c81f7c583eb6..3d70bc62dd2cf 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7245,6 +7245,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}} +}; + + >From b969ec109b28521af51f5d3a3ed71eb6f050c955 Mon Sep 17 00:00:00 2001 From: Vincent <l...@viceroygroup.ca> Date: Mon, 12 May 2025 08:10:06 -0400 Subject: [PATCH 2/4] Added Release Notes and moved comments and minor nits. --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaExpr.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 44c38396c764f..82d2e60ccc077 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -589,6 +589,7 @@ Bug Fixes in This Version - Fixed a crash with an invalid member function parameter list with a default argument which contains a pragma. (#GH113722) - Fixed assertion failures when generating name lookup table in modules. (#GH61065, #GH134739) +- Fixed an assertion failure in constant compound literal statements. (#GH139160) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3d70bc62dd2cf..2d59999c7e396 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7241,16 +7241,16 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, ? VK_PRValue : VK_LValue; + // 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 (IsFileScope) 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)) { + if (!Init->isConstantInitializer(Context, /*IsForRef=*/false)) { Diag(Init->getExprLoc(), diag::err_init_element_not_constant) << Init->getSourceBitField(); return ExprError(); >From 80b072e6343b6469e9f4f66e3fb99184b263d416 Mon Sep 17 00:00:00 2001 From: Vincent <l...@viceroygroup.ca> Date: Wed, 14 May 2025 14:04:37 -0400 Subject: [PATCH 3/4] Remove Redundant Check --- clang/lib/Sema/SemaExpr.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2d59999c7e396..637c3c927fd6f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7248,8 +7248,7 @@ 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); - if (!Init->isTypeDependent() && !Init->isValueDependent() && - !Init->getType()->isDependentType()) + if (!Init->isTypeDependent() && !Init->isValueDependent()) if (!Init->isConstantInitializer(Context, /*IsForRef=*/false)) { Diag(Init->getExprLoc(), diag::err_init_element_not_constant) << Init->getSourceBitField(); >From ca92bd0ec02b44593ff02b3ad691a1a5725eec93 Mon Sep 17 00:00:00 2001 From: Aaron Ballman <aa...@aaronballman.com> Date: Thu, 15 May 2025 12:23:27 -0400 Subject: [PATCH 4/4] Update clang/lib/Sema/SemaExpr.cpp --- clang/lib/Sema/SemaExpr.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 637c3c927fd6f..08a3fec7de5e5 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7248,12 +7248,12 @@ 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); - if (!Init->isTypeDependent() && !Init->isValueDependent()) - if (!Init->isConstantInitializer(Context, /*IsForRef=*/false)) { - Diag(Init->getExprLoc(), diag::err_init_element_not_constant) - << Init->getSourceBitField(); - return ExprError(); - } + if (!Init->isTypeDependent() && !Init->isValueDependent() && + !Init->isConstantInitializer(Context, /*IsForRef=*/false)) { + Diag(Init->getExprLoc(), diag::err_init_element_not_constant) + << Init->getSourceBitField(); + return ExprError(); + } ILE->setInit(i, ConstantExpr::Create(Context, Init)); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits