[PATCH] D42731: [IR] - Make User construction exception safe
Klaus Kretzschmar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 31 04:14:23 PST 2018
kkretzsch created this revision.
kkretzsch added reviewers: pete, MatzeB.
There are many instruction ctors that call the setName method of the Value base class, which can throw a bad_alloc exception in OOM situations. In such situations special User delete operators are called which are not implemented yet.
Note that some User subclasses change the information which is required to calculate the storage pointer of a User object (e.g.NumUserOperands). Those subclasses need an operator delete that restores the changed information to its original value. Example: GlobalVariable.h
Repository:
rL LLVM
https://reviews.llvm.org/D42731
Files:
include/llvm/IR/GlobalVariable.h
include/llvm/IR/User.h
Index: include/llvm/IR/User.h
===================================================================
--- include/llvm/IR/User.h
+++ include/llvm/IR/User.h
@@ -99,13 +99,31 @@
/// \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) {
+ // called when constructor throws.
+ // 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) {
+ // called when constructor throws.
+ // 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:
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<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);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42731.132124.patch
Type: text/x-patch
Size: 2767 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180131/460c1f56/attachment.bin>
More information about the llvm-commits
mailing list