[clang] [clang] Fix C23 constexpr crashes (PR #112708)
Mariya Podchishchaeva via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 17 08:12:13 PDT 2024
https://github.com/Fznamznon updated https://github.com/llvm/llvm-project/pull/112708
>From c40ea631fc1ec226b644b1df2d1dca1c8646c992 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Thu, 17 Oct 2024 06:43:13 -0700
Subject: [PATCH 1/2] [clang] Fix C23 constexpr crashes
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
---
clang/lib/AST/Decl.cpp | 6 ++++--
clang/test/Sema/constexpr.c | 17 +++++++++++++++++
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index f083ffff87a8ec..c642fcf8785151 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -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
@@ -2620,7 +2621,8 @@ 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)
+ if (hasGlobalStorage() && !getASTContext().getLangOpts().CPlusPlus &&
+ !isConstexpr())
return true;
// In C++, it depends on whether the evaluation at the point of definition
diff --git a/clang/test/Sema/constexpr.c b/clang/test/Sema/constexpr.c
index eaa000b3b97758..3dcb0b3a7d95fd 100644
--- a/clang/test/Sema/constexpr.c
+++ b/clang/test/Sema/constexpr.c
@@ -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}}
+}
>From d1406be551dedd4bfe7d221d43d8fd0787ce85e3 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishchaeva at intel.com>
Date: Thu, 17 Oct 2024 08:11:45 -0700
Subject: [PATCH 2/2] Extend the comment
---
clang/lib/AST/Decl.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index c642fcf8785151..8321cee0e0bc94 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2620,7 +2620,9 @@ bool VarDecl::hasICEInitializer(const ASTContext &Context) const {
}
bool VarDecl::hasConstantInitialization() const {
- // In C, all globals (and only globals) have constant initialization.
+ // 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;
More information about the cfe-commits
mailing list