[clang] a52c0c7 - [clang][Interp] Lazily visit constant locals in C++

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 16 03:49:18 PST 2024


Author: Timm Bäder
Date: 2024-02-16T12:49:05+01:00
New Revision: a52c0c770056e040390839e753dbbaccbf4d63c4

URL: https://github.com/llvm/llvm-project/commit/a52c0c770056e040390839e753dbbaccbf4d63c4
DIFF: https://github.com/llvm/llvm-project/commit/a52c0c770056e040390839e753dbbaccbf4d63c4.diff

LOG: [clang][Interp] Lazily visit constant locals in C++

While we _do_ get them registered via visitInitializer(), they
are still local, so gone on the next call to e.g. evaluateAsRValue().

Visit them lazily, similarly like we do in C.

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/test/AST/Interp/arrays.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index a27a0cb2094eae..975d3b68e9b242 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3237,9 +3237,20 @@ bool ByteCodeExprGen<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) {
   // Try to lazily visit (or emit dummy pointers for) declarations
   // we haven't seen yet.
   if (Ctx.getLangOpts().CPlusPlus) {
-    if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isStaticLocal()) {
-      if (std::optional<unsigned> I = P.getOrCreateDummy(D))
-        return this->emitGetPtrGlobal(*I, E);
+    if (const auto *VD = dyn_cast<VarDecl>(D)) {
+      // Dummy for static locals
+      if (VD->isStaticLocal()) {
+        if (std::optional<unsigned> I = P.getOrCreateDummy(D))
+          return this->emitGetPtrGlobal(*I, E);
+        return false;
+      }
+      // Visit local const variables like normal.
+      if (VD->isLocalVarDecl() && VD->getType().isConstQualified()) {
+        if (!this->visitVarDecl(VD))
+          return false;
+        // Retry.
+        return this->VisitDeclRefExpr(E);
+      }
     }
   } else {
     if (const auto *VD = dyn_cast<VarDecl>(D);

diff  --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp
index 3c06ab5fbe3657..a9450d827f6be6 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -537,3 +537,11 @@ namespace SelfComparison {
     return s3->array[t.field] == s3->array[t.field];  // both-warning {{self-comparison always evaluates to true}}
   };
 }
+
+namespace LocalIndex {
+  void test() {
+    const int const_subscript = 3;
+    int array[2]; // both-note {{declared here}}
+    array[const_subscript] = 0;  // both-warning {{array index 3 is past the end of the array (that has type 'int[2]')}}
+  }
+}


        


More information about the cfe-commits mailing list