diff options
-rw-r--r-- | llvm/include/llvm/IR/GlobalVariable.h | 13 | ||||
-rw-r--r-- | llvm/include/llvm/IR/User.h | 24 |
2 files changed, 30 insertions, 7 deletions
diff --git a/llvm/include/llvm/IR/GlobalVariable.h b/llvm/include/llvm/IR/GlobalVariable.h index 34ace6f2b4f..03b9ec46ebb 100644 --- a/llvm/include/llvm/IR/GlobalVariable.h +++ b/llvm/include/llvm/IR/GlobalVariable.h @@ -68,9 +68,6 @@ public: ~GlobalVariable() { dropAllReferences(); - - // FIXME: needed by operator delete - setGlobalVariableNumOperands(1); } // allocate space for exactly one operand @@ -78,6 +75,16 @@ public: 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); diff --git a/llvm/include/llvm/IR/User.h b/llvm/include/llvm/IR/User.h index 4dfa19cf241..9d30be0270e 100644 --- a/llvm/include/llvm/IR/User.h +++ b/llvm/include/llvm/IR/User.h @@ -99,13 +99,29 @@ public: /// \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: |