Skip to content

Commit abfba7d

Browse files
authored
[clang] Fix C23 constexpr crashes (#112708)
Before using a constexpr variable that is not properly initialized check that it is valid. Fixes #109095 Fixes #112516
1 parent 09cc75e commit abfba7d

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

clang/lib/AST/Decl.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2512,7 +2512,8 @@ bool VarDecl::isUsableInConstantExpressions(const ASTContext &Context) const {
25122512
if (!DefVD->mightBeUsableInConstantExpressions(Context))
25132513
return false;
25142514
// ... and its initializer is a constant initializer.
2515-
if (Context.getLangOpts().CPlusPlus && !DefVD->hasConstantInitialization())
2515+
if ((Context.getLangOpts().CPlusPlus || getLangOpts().C23) &&
2516+
!DefVD->hasConstantInitialization())
25162517
return false;
25172518
// C++98 [expr.const]p1:
25182519
// An integral constant-expression can involve only [...] const variables
@@ -2619,8 +2620,11 @@ bool VarDecl::hasICEInitializer(const ASTContext &Context) const {
26192620
}
26202621

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

26262630
// In C++, it depends on whether the evaluation at the point of definition

clang/test/Sema/constexpr.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,3 +374,20 @@ void constexprif() {
374374
void constevalif() {
375375
if consteval (300) {} //expected-error {{expected '(' after 'if'}}
376376
}
377+
378+
struct S11 {
379+
int len;
380+
};
381+
void ghissue112516() {
382+
struct S11 *s11 = 0;
383+
constexpr int num = s11->len; // expected-error {{constexpr variable 'num' must be initialized by a constant expression}}
384+
void *Arr[num];
385+
}
386+
387+
void ghissue109095() {
388+
constexpr char c[] = { 'a' };
389+
constexpr int i = c[1]; // expected-error {{constexpr variable 'i' must be initialized by a constant expression}}\
390+
// expected-note {{declared here}}
391+
_Static_assert(i == c[0]); // expected-error {{static assertion expression is not an integral constant expression}}\
392+
// expected-note {{initializer of 'i' is not a constant expression}}
393+
}

0 commit comments

Comments
 (0)