[clang] [clang][bytecode] Revisit global variables separately (PR #123358)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 17 07:36:42 PST 2025


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

Call `EvaluateAsInitializer()` explicitly here, so we don't abort the evaluation of the `DeflRefExpr` just because the initializer of that global variable failed.

>From 8dac131d58f4c6dc4ddb58c3933e7726d65f9d34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Fri, 17 Jan 2025 16:32:18 +0100
Subject: [PATCH] [clang][bytecode] Revisit global variables separately

Call `EvaluateAsInitializer()` explicitly here, so we don't abort
the evaluation of the `DeflRefExpr` just because the initializer of
that global variable failed.
---
 clang/lib/AST/ByteCode/Compiler.cpp | 14 +++++++++++++-
 clang/test/AST/ByteCode/cxx98.cpp   |  5 +++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index fca8518575594f..3ef2b0858e667b 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -6210,8 +6210,20 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
           return revisit(VD);
 
         if ((VD->hasGlobalStorage() || VD->isStaticDataMember()) &&
-            typeShouldBeVisited(VD->getType()))
+            typeShouldBeVisited(VD->getType())) {
+          if (const Expr *Init = VD->getAnyInitializer();
+              Init && !Init->isValueDependent()) {
+            // Whether or not the evaluation is successul doesn't really matter
+            // here -- we will create a global variable in any case, and that
+            // will have the state of initializer evaluation attached.
+            APValue V;
+            SmallVector<PartialDiagnosticAt> Notes;
+            (void)Init->EvaluateAsInitializer(V, Ctx.getASTContext(), VD, Notes,
+                                              true);
+            return this->visitDeclRef(D, E);
+          }
           return revisit(VD);
+        }
 
         // FIXME: The evaluateValue() check here is a little ridiculous, since
         // it will ultimately call into Context::evaluateAsInitializer(). In
diff --git a/clang/test/AST/ByteCode/cxx98.cpp b/clang/test/AST/ByteCode/cxx98.cpp
index 20f98d33c31c4f..c17049b01c1daf 100644
--- a/clang/test/AST/ByteCode/cxx98.cpp
+++ b/clang/test/AST/ByteCode/cxx98.cpp
@@ -59,3 +59,8 @@ struct PR65784s{
   int *ptr;
 } const PR65784[] = {(int *)""};
 PR65784s PR65784f() { return *PR65784; }
+
+const int b = 1 / 0; // both-warning {{division by zero is undefined}} \
+                     // both-note {{declared here}}
+_Static_assert(b, ""); // both-error {{not an integral constant expression}} \
+                       // both-note {{initializer of 'b' is not a constant expression}}



More information about the cfe-commits mailing list