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.podchishcha...@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.podchishcha...@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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits