summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Seaborn <mseaborn@chromium.org>2013-12-08 00:51:21 +0000
committerMark Seaborn <mseaborn@chromium.org>2013-12-08 00:51:21 +0000
commit1b3dd3527ee717a55641a5fd1a85f7ac6aa1c857 (patch)
tree4df41fbbaf149593f8680e6cf26f916ba2c71dc5
parentef3dbb93ecd7bf51d39f5d06fcdf137e8c1b5b76 (diff)
downloadbcm5719-llvm-1b3dd3527ee717a55641a5fd1a85f7ac6aa1c857.tar.gz
bcm5719-llvm-1b3dd3527ee717a55641a5fd1a85f7ac6aa1c857.zip
Fix inlining to not lose the "cleanup" clause from landingpads
This fixes PR17872. This bug can lead to C++ destructors not being called when they should be, when an exception is thrown. llvm-svn: 196711
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp2
-rw-r--r--llvm/test/Transforms/Inline/invoke-cleanup.ll39
2 files changed, 41 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 405f77e793f..e35a1d0b006 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -238,6 +238,8 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
InlinedLPad->reserveClauses(OuterNum);
for (unsigned OuterIdx = 0; OuterIdx != OuterNum; ++OuterIdx)
InlinedLPad->addClause(OuterLPad->getClause(OuterIdx));
+ if (OuterLPad->isCleanup())
+ InlinedLPad->setCleanup(true);
}
for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E; ++BB){
diff --git a/llvm/test/Transforms/Inline/invoke-cleanup.ll b/llvm/test/Transforms/Inline/invoke-cleanup.ll
new file mode 100644
index 00000000000..457ae2addeb
--- /dev/null
+++ b/llvm/test/Transforms/Inline/invoke-cleanup.ll
@@ -0,0 +1,39 @@
+; RUN: opt %s -inline -S | FileCheck %s
+
+declare void @external_func()
+
+@exception_type1 = external global i8
+@exception_type2 = external global i8
+
+
+define internal void @inner() {
+ invoke void @external_func()
+ to label %cont unwind label %lpad
+cont:
+ ret void
+lpad:
+ %lp = landingpad i32 personality i8* null
+ catch i8* @exception_type1
+ resume i32 %lp
+}
+
+; Test that the "cleanup" clause is kept when inlining @inner() into
+; this call site (PR17872), otherwise C++ destructors will not be
+; called when they should be.
+
+define void @outer() {
+ invoke void @inner()
+ to label %cont unwind label %lpad
+cont:
+ ret void
+lpad:
+ %lp = landingpad i32 personality i8* null
+ cleanup
+ catch i8* @exception_type2
+ resume i32 %lp
+}
+; CHECK: define void @outer
+; CHECK: landingpad
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: catch i8* @exception_type1
+; CHECK-NEXT: catch i8* @exception_type2
OpenPOWER on IntegriCloud