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]')}} + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits