tbaeder updated this revision to Diff 478598.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D138275/new/

https://reviews.llvm.org/D138275

Files:
  clang/lib/AST/Interp/InterpFrame.cpp
  clang/lib/AST/Interp/InterpFrame.h
  clang/lib/AST/Interp/InterpState.cpp
  clang/lib/AST/Interp/InterpState.h
  clang/test/AST/Interp/cxx20.cpp

Index: clang/test/AST/Interp/cxx20.cpp
===================================================================
--- clang/test/AST/Interp/cxx20.cpp
+++ clang/test/AST/Interp/cxx20.cpp
@@ -304,3 +304,15 @@
   }
   static_assert(testInc2() == 1, "");
 };
+
+constexpr int NoLeakHere() {
+  int abc[2];
+
+  abc[0] = 1;
+  return abc[1]; // expected-note {{read of object outside its lifetime}} \
+                 // ref-note {{read of uninitialized object}}
+}
+static_assert(NoLeakHere() == 3); // expected-error {{not an integral constant expression}} \
+                                  // expected-note {{in call to}} \
+                                  // ref-error {{not an integral constant expression}} \
+                                  // ref-note {{in call to}}
Index: clang/lib/AST/Interp/InterpState.h
===================================================================
--- clang/lib/AST/Interp/InterpState.h
+++ clang/lib/AST/Interp/InterpState.h
@@ -78,9 +78,12 @@
   /// Reports overflow and return true if evaluation should continue.
   bool reportOverflow(const Expr *E, const llvm::APSInt &Value);
 
-  /// Deallocates a pointer.
+  /// Deallocates a block.
   void deallocate(Block *B);
 
+  /// Destroys a block, used during tear down.
+  void destroy(Block *B);
+
   /// Delegates source mapping to the mapper.
   SourceInfo getSource(const Function *F, CodePtr PC) const override {
     return M ? M->getSource(F, PC) : F->getSource(PC);
Index: clang/lib/AST/Interp/InterpState.cpp
===================================================================
--- clang/lib/AST/Interp/InterpState.cpp
+++ clang/lib/AST/Interp/InterpState.cpp
@@ -54,6 +54,15 @@
   return noteUndefinedBehavior();
 }
 
+void InterpState::destroy(Block *B) {
+  assert(B);
+  Descriptor *Desc = B->getDescriptor();
+  assert(Desc);
+  // Free storage, if necessary.
+  if (Desc->DtorFn)
+    Desc->DtorFn(B, B->data(), Desc);
+}
+
 void InterpState::deallocate(Block *B) {
   Descriptor *Desc = B->getDescriptor();
   if (B->hasPointers()) {
@@ -68,7 +77,6 @@
       Desc->MoveFn(B, B->data(), D->data(), Desc);
   } else {
     // Free storage, if necessary.
-    if (Desc->DtorFn)
-      Desc->DtorFn(B, B->data(), Desc);
+    destroy(B);
   }
 }
Index: clang/lib/AST/Interp/InterpFrame.h
===================================================================
--- clang/lib/AST/Interp/InterpFrame.h
+++ clang/lib/AST/Interp/InterpFrame.h
@@ -47,6 +47,11 @@
   /// Invokes the destructors for a scope.
   void destroy(unsigned Idx);
 
+  /// Invokes the destructors for all scopes. This is used in the
+  /// InterpFrame destructor to avoid memory leaks in case the
+  /// interpretation was not successful.
+  void destroyAll();
+
   /// Pops the arguments off the stack.
   void popArgs();
 
Index: clang/lib/AST/Interp/InterpFrame.cpp
===================================================================
--- clang/lib/AST/Interp/InterpFrame.cpp
+++ clang/lib/AST/Interp/InterpFrame.cpp
@@ -64,6 +64,7 @@
 }
 
 InterpFrame::~InterpFrame() {
+  destroyAll();
   for (auto &Param : Params)
     S.deallocate(reinterpret_cast<Block *>(Param.second.get()));
 }
@@ -74,6 +75,16 @@
   }
 }
 
+void InterpFrame::destroyAll() {
+  if (!Func)
+    return;
+  for (const Scope &Sc : Func->scopes()) {
+    for (auto &Local : Sc.locals()) {
+      S.destroy(reinterpret_cast<Block *>(localBlock(Local.Offset)));
+    }
+  }
+}
+
 void InterpFrame::popArgs() {
   for (PrimType Ty : Func->args_reverse())
     TYPE_SWITCH(Ty, S.Stk.discard<T>());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D138275: [clang][Inter... Timm Bäder via Phabricator via cfe-commits

Reply via email to