mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-19 13:26:45 +00:00
[clang] Fix C23 constexpr crashes (#112708)
Before using a constexpr variable that is not properly initialized check that it is valid. Fixes https://github.com/llvm/llvm-project/issues/109095 Fixes https://github.com/llvm/llvm-project/issues/112516
This commit is contained in:
parent
81005af65f
commit
c9e8540d6c
@ -2503,7 +2503,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
|
||||
@ -2610,8 +2611,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
|
||||
|
@ -364,3 +364,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…
x
Reference in New Issue
Block a user