Index: include/llvm/IR/GlobalVariable.h =================================================================== --- include/llvm/IR/GlobalVariable.h +++ include/llvm/IR/GlobalVariable.h @@ -68,9 +68,6 @@ ~GlobalVariable() { dropAllReferences(); - - // FIXME: needed by operator delete - setGlobalVariableNumOperands(1); } // allocate space for exactly one operand @@ -78,6 +75,16 @@ 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(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: include/llvm/IR/User.h =================================================================== --- include/llvm/IR/User.h +++ 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: