summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/GlobalVariable.h13
-rw-r--r--llvm/include/llvm/IR/User.h24
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:
OpenPOWER on IntegriCloud