[PATCH] D42731: [IR] - Make User construction exception safe

Phabricator via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 28 03:34:46 PST 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rL326316: [IR] - Make User construction exception safe (authored by kkretzschmar, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D42731?vs=134597&id=136268#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D42731

Files:
  llvm/trunk/include/llvm/IR/GlobalVariable.h
  llvm/trunk/include/llvm/IR/User.h


Index: llvm/trunk/include/llvm/IR/GlobalVariable.h
===================================================================
--- llvm/trunk/include/llvm/IR/GlobalVariable.h
+++ llvm/trunk/include/llvm/IR/GlobalVariable.h
@@ -68,16 +68,23 @@
 
   ~GlobalVariable() {
     dropAllReferences();
-
-    // FIXME: needed by operator delete
-    setGlobalVariableNumOperands(1);
   }
 
   // allocate space for exactly one operand
   void *operator new(size_t s) {
     return User::operator new(s, 1);
   }
 
+  // delete space for exactly one operand as created in the corresponding new operator
+  void operator delete(void *ptr){
+    assert(ptr != nullptr && "must not be nullptr");
+    User *Obj = static_cast<User *>(ptr);
+    // Number of operands can be set to 0 after construction and initialization. Make sure
+    // that number of operands is reset to 1, as this is needed in User::operator delete
+    Obj->setGlobalVariableNumOperands(1);
+    User::operator delete(Obj);
+  }
+
   /// Provide fast operand accessors
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 
Index: llvm/trunk/include/llvm/IR/User.h
===================================================================
--- llvm/trunk/include/llvm/IR/User.h
+++ llvm/trunk/include/llvm/IR/User.h
@@ -99,13 +99,29 @@
 
   /// \brief Free memory allocated for User and Use objects.
   void operator delete(void *Usr);
-  /// \brief Placement delete - required by std, but never called.
-  void operator delete(void*, unsigned) {
+  /// \brief Placement delete - required by std, called if the ctor throws.
+  void operator delete(void *Usr, unsigned) {
+    // Note: If a subclass manipulates the information which is required to calculate the 
+    // Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has 
+    // to restore the changed information to the original value, since the dtor of that class
+    // is not called if the ctor fails.  
+    User::operator delete(Usr);
+
+#ifndef LLVM_ENABLE_EXCEPTIONS
     llvm_unreachable("Constructor throws?");
+#endif
   }
-  /// \brief Placement delete - required by std, but never called.
-  void operator delete(void*, unsigned, bool) {
+  /// \brief Placement delete - required by std, called if the ctor throws.
+  void operator delete(void *Usr, unsigned, bool) {
+    // Note: If a subclass manipulates the information which is required to calculate the 
+    // Usr memory pointer, e.g. NumUserOperands, the operator delete of that subclass has 
+    // to restore the changed information to the original value, since the dtor of that class
+    // is not called if the ctor fails.  
+    User::operator delete(Usr);
+
+#ifndef LLVM_ENABLE_EXCEPTIONS
     llvm_unreachable("Constructor throws?");
+#endif
   }
 
 protected:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42731.136268.patch
Type: text/x-patch
Size: 2770 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180228/522b2bdf/attachment.bin>


More information about the llvm-commits mailing list