[clang] 16c721f - [clang][bytecode] Destroy local variables in reverse order (#125727)

via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 4 23:09:18 PST 2025


Author: Timm Baeder
Date: 2025-02-05T08:09:13+01:00
New Revision: 16c721f2d1bf5ebbde1b3df103761b45f266a5ec

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

LOG: [clang][bytecode] Destroy local variables in reverse order (#125727)

See the attached test case.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Function.h
    clang/lib/AST/ByteCode/InterpFrame.cpp
    clang/test/AST/ByteCode/cxx20.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Function.h b/clang/lib/AST/ByteCode/Function.h
index 2d3421e5e61295..e17183eef9eac6 100644
--- a/clang/lib/AST/ByteCode/Function.h
+++ b/clang/lib/AST/ByteCode/Function.h
@@ -51,6 +51,11 @@ class Scope final {
     return llvm::make_range(Descriptors.begin(), Descriptors.end());
   }
 
+  llvm::iterator_range<LocalVectorTy::const_reverse_iterator>
+  locals_reverse() const {
+    return llvm::reverse(Descriptors);
+  }
+
 private:
   /// Object descriptors in this block.
   LocalVectorTy Descriptors;

diff  --git a/clang/lib/AST/ByteCode/InterpFrame.cpp b/clang/lib/AST/ByteCode/InterpFrame.cpp
index 89fc7a4515d641..c383b2bc7f95ce 100644
--- a/clang/lib/AST/ByteCode/InterpFrame.cpp
+++ b/clang/lib/AST/ByteCode/InterpFrame.cpp
@@ -99,7 +99,7 @@ void InterpFrame::initScope(unsigned Idx) {
 }
 
 void InterpFrame::destroy(unsigned Idx) {
-  for (auto &Local : Func->getScope(Idx).locals()) {
+  for (auto &Local : Func->getScope(Idx).locals_reverse()) {
     S.deallocate(localBlock(Local.Offset));
   }
 }

diff  --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp
index 268226a7c143ed..a63aea1ea5548b 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -908,3 +908,26 @@ namespace TemporaryInNTTP {
                // expected-note {{created here}}
   B<2> j2; /// Ok.
 }
+
+namespace LocalDestroy {
+  /// This is reduced from a libc++ test case.
+  /// The local f.TI.copied points to the local variable Copied, and we used to
+  /// destroy Copied before f, causing problems later on when a DeadBlock had a
+  /// pointer pointing to it that was already destroyed.
+  struct TrackInitialization {
+    bool *copied_;
+  };
+  struct TrackingPred : TrackInitialization {
+    constexpr TrackingPred(bool *copied) : TrackInitialization(copied) {}
+  };
+  struct F {
+    const TrackingPred &TI;
+  };
+  constexpr int f() {
+    bool Copied = false;
+    TrackingPred TI(&Copied);
+    F f{TI};
+    return 1;
+  }
+  static_assert(f() == 1);
+}


        


More information about the cfe-commits mailing list