[clang] [clang][bytecode] Fix reporting failed local constexpr initializers (PR #123588)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 20 03:20:02 PST 2025


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/123588

We need to emit the 'initializer of X is not a constant expression' note for local constexpr variables as well.

>From 8ce1601e272429601c5a1e292c2cd1b9a6afb6a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 20 Jan 2025 12:18:18 +0100
Subject: [PATCH] [clang][bytecode] Fix reporting failed local constexpr
 initializers

We need to emit the 'initializer of X is not a constant expression'
note for local constexpr variables as well.
---
 clang/lib/AST/ByteCode/Interp.cpp    | 10 ++++++----
 clang/test/AST/ByteCode/c23.c        |  8 ++++++++
 clang/test/AST/ByteCode/literals.cpp |  9 +++++++++
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 4b26cc66cd09ad..c765ebf5d618ee 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -416,9 +416,11 @@ bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
                 AccessKinds AK) {
   if (!Ptr.isOnePastEnd())
     return true;
-  const SourceInfo &Loc = S.Current->getSource(OpPC);
-  S.FFDiag(Loc, diag::note_constexpr_access_past_end)
-      << AK << S.Current->getRange(OpPC);
+  if (S.getLangOpts().CPlusPlus) {
+    const SourceInfo &Loc = S.Current->getSource(OpPC);
+    S.FFDiag(Loc, diag::note_constexpr_access_past_end)
+        << AK << S.Current->getRange(OpPC);
+  }
   return false;
 }
 
@@ -538,7 +540,7 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
     return true;
 
   if (const auto *VD = Ptr.getDeclDesc()->asVarDecl();
-      VD && VD->hasGlobalStorage()) {
+      VD && (VD->isConstexpr() || VD->hasGlobalStorage())) {
     const SourceInfo &Loc = S.Current->getSource(OpPC);
     if (VD->getAnyInitializer()) {
       S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
diff --git a/clang/test/AST/ByteCode/c23.c b/clang/test/AST/ByteCode/c23.c
index 5154d57f6cb9e7..0e9851aa2ad3a5 100644
--- a/clang/test/AST/ByteCode/c23.c
+++ b/clang/test/AST/ByteCode/c23.c
@@ -49,3 +49,11 @@ static_assert(arg1[1] == 254);
 static_assert(arg1[2] == 186);
 static_assert(arg1[3] == 190);
 #endif
+
+void ghissue109095() {
+  constexpr char c[] = { 'a' };
+  constexpr int i = c[1]; // both-error {{constexpr variable 'i' must be initialized by a constant expression}}\
+                          // both-note {{declared here}}
+  _Static_assert(i == c[0]); // both-error {{static assertion expression is not an integral constant expression}}\
+                             // both-note {{initializer of 'i' is not a constant expression}}
+}
diff --git a/clang/test/AST/ByteCode/literals.cpp b/clang/test/AST/ByteCode/literals.cpp
index fdf1a6820e4466..b75ca2b19a969a 100644
--- a/clang/test/AST/ByteCode/literals.cpp
+++ b/clang/test/AST/ByteCode/literals.cpp
@@ -1315,3 +1315,12 @@ namespace {
   }
 }
 #endif
+
+void localConstexpr() {
+  constexpr int a = 1/0; // both-error {{must be initialized by a constant expression}} \
+                         // both-note {{division by zero}} \
+                         // both-warning {{division by zero is undefined}} \
+                         // both-note {{declared here}}
+  static_assert(a == 0, ""); // both-error {{not an integral constant expression}} \
+                             // both-note {{initializer of 'a' is not a constant expression}}
+}



More information about the cfe-commits mailing list