Skip to content

[clang] Fix C23 constexpr crashes #112708

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 7 additions & 3 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2512,7 +2512,8 @@ bool VarDecl::isUsableInConstantExpressions(const ASTContext &Context) const {
if (!DefVD->mightBeUsableInConstantExpressions(Context))
return false;
// ... and its initializer is a constant initializer.
if (Context.getLangOpts().CPlusPlus && !DefVD->hasConstantInitialization())
if ((Context.getLangOpts().CPlusPlus || getLangOpts().C23) &&
!DefVD->hasConstantInitialization())
return false;
// C++98 [expr.const]p1:
// An integral constant-expression can involve only [...] const variables
Expand Down Expand Up @@ -2619,8 +2620,11 @@ bool VarDecl::hasICEInitializer(const ASTContext &Context) const {
}

bool VarDecl::hasConstantInitialization() const {
// In C, all globals (and only globals) have constant initialization.
if (hasGlobalStorage() && !getASTContext().getLangOpts().CPlusPlus)
// In C, all globals and constexpr variables should have constant
// initialization. For constexpr variables in C check that initializer is a
// constant initializer because they can be used in constant expressions.
if (hasGlobalStorage() && !getASTContext().getLangOpts().CPlusPlus &&
!isConstexpr())
return true;

// In C++, it depends on whether the evaluation at the point of definition
Expand Down
17 changes: 17 additions & 0 deletions clang/test/Sema/constexpr.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,20 @@ void constexprif() {
void constevalif() {
if consteval (300) {} //expected-error {{expected '(' after 'if'}}
}

struct S11 {
int len;
};
void ghissue112516() {
struct S11 *s11 = 0;
constexpr int num = s11->len; // expected-error {{constexpr variable 'num' must be initialized by a constant expression}}
void *Arr[num];
}

void ghissue109095() {
constexpr char c[] = { 'a' };
constexpr int i = c[1]; // expected-error {{constexpr variable 'i' must be initialized by a constant expression}}\
// expected-note {{declared here}}
_Static_assert(i == c[0]); // expected-error {{static assertion expression is not an integral constant expression}}\
// expected-note {{initializer of 'i' is not a constant expression}}
}
Loading