[llvm] r244563 - [IR] Verify EH pad predecessors

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 10 19:48:30 PDT 2015


Author: majnemer
Date: Mon Aug 10 21:48:30 2015
New Revision: 244563

URL: http://llvm.org/viewvc/llvm-project?rev=244563&view=rev
Log:
[IR] Verify EH pad predecessors

Make sure that an EH pad's predecessors are using their unwind edge to
transfer control to the EH pad.

Modified:
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/test/Feature/exception.ll

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=244563&r1=244562&r2=244563&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Mon Aug 10 21:48:30 2015
@@ -392,6 +392,7 @@ private:
   void visitAllocaInst(AllocaInst &AI);
   void visitExtractValueInst(ExtractValueInst &EVI);
   void visitInsertValueInst(InsertValueInst &IVI);
+  void visitEHPadPredecessors(Instruction &I);
   void visitLandingPadInst(LandingPadInst &LPI);
   void visitCatchPadInst(CatchPadInst &CPI);
   void visitCatchEndPadInst(CatchEndPadInst &CEPI);
@@ -2774,23 +2775,54 @@ void Verifier::visitInsertValueInst(Inse
   visitInstruction(IVI);
 }
 
-void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
-  BasicBlock *BB = LPI.getParent();
+void Verifier::visitEHPadPredecessors(Instruction &I) {
+  assert(I.isEHPad());
+
+  BasicBlock *BB = I.getParent();
+  Function *F = BB->getParent();
+
+  Assert(BB != &F->getEntryBlock(), "EH pad cannot be in entry block.", &I);
+
+  if (auto *LPI = dyn_cast<LandingPadInst>(&I)) {
+    // The landingpad instruction defines its parent as a landing pad block. The
+    // landing pad block may be branched to only by the unwind edge of an
+    // invoke.
+    for (BasicBlock *PredBB : predecessors(BB)) {
+      const auto *II = dyn_cast<InvokeInst>(PredBB->getTerminator());
+      Assert(II && II->getUnwindDest() == BB && II->getNormalDest() != BB,
+             "Block containing LandingPadInst must be jumped to "
+             "only by the unwind edge of an invoke.",
+             LPI);
+    }
+    return;
+  }
+
+  for (BasicBlock *PredBB : predecessors(BB)) {
+    TerminatorInst *TI = PredBB->getTerminator();
+    if (auto *II = dyn_cast<InvokeInst>(TI))
+      Assert(II->getUnwindDest() == BB && II->getNormalDest() != BB,
+             "EH pad must be jumped to via an unwind edge", &I, II);
+    else if (auto *CPI = dyn_cast<CatchPadInst>(TI))
+      Assert(CPI->getUnwindDest() == BB && CPI->getNormalDest() != BB,
+             "EH pad must be jumped to via an unwind edge", &I, CPI);
+    else if (isa<CatchEndPadInst>(TI))
+      ;
+    else if (isa<CleanupReturnInst>(TI))
+      ;
+    else if (isa<TerminatePadInst>(TI))
+      ;
+    else
+      Assert(false, "EH pad must be jumped to via an unwind edge", &I, TI);
+  }
+}
 
+void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
   // The landingpad instruction is ill-formed if it doesn't have any clauses and
   // isn't a cleanup.
   Assert(LPI.getNumClauses() > 0 || LPI.isCleanup(),
          "LandingPadInst needs at least one clause or to be a cleanup.", &LPI);
 
-  // The landingpad instruction defines its parent as a landing pad block. The
-  // landing pad block may be branched to only by the unwind edge of an invoke.
-  for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I) {
-    const InvokeInst *II = dyn_cast<InvokeInst>((*I)->getTerminator());
-    Assert(II && II->getUnwindDest() == BB && II->getNormalDest() != BB,
-           "Block containing LandingPadInst must be jumped to "
-           "only by the unwind edge of an invoke.",
-           &LPI);
-  }
+  visitEHPadPredecessors(LPI);
 
   if (!LandingPadResultTy)
     LandingPadResultTy = LPI.getType();
@@ -2826,7 +2858,7 @@ void Verifier::visitLandingPadInst(Landi
 }
 
 void Verifier::visitCatchPadInst(CatchPadInst &CPI) {
-  BasicBlock *BB = CPI.getParent();
+  visitEHPadPredecessors(CPI);
 
   if (!CatchPadResultTy)
     CatchPadResultTy = CPI.getType();
@@ -2836,6 +2868,7 @@ void Verifier::visitCatchPadInst(CatchPa
            "inside a function.",
            &CPI);
 
+  BasicBlock *BB = CPI.getParent();
   Function *F = BB->getParent();
   Assert(F->hasPersonalityFn(),
          "CatchPadInst needs to be in a function with a personality.", &CPI);
@@ -2857,8 +2890,9 @@ void Verifier::visitCatchPadInst(CatchPa
 }
 
 void Verifier::visitCatchEndPadInst(CatchEndPadInst &CEPI) {
-  BasicBlock *BB = CEPI.getParent();
+  visitEHPadPredecessors(CEPI);
 
+  BasicBlock *BB = CEPI.getParent();
   Function *F = BB->getParent();
   Assert(F->hasPersonalityFn(),
          "CatchEndPadInst needs to be in a function with a personality.",
@@ -2891,6 +2925,8 @@ void Verifier::visitCatchEndPadInst(Catc
 }
 
 void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) {
+  visitEHPadPredecessors(CPI);
+
   BasicBlock *BB = CPI.getParent();
 
   if (!CleanupPadResultTy)
@@ -2927,8 +2963,9 @@ void Verifier::visitCleanupReturnInst(Cl
 }
 
 void Verifier::visitTerminatePadInst(TerminatePadInst &TPI) {
-  BasicBlock *BB = TPI.getParent();
+  visitEHPadPredecessors(TPI);
 
+  BasicBlock *BB = TPI.getParent();
   Function *F = BB->getParent();
   Assert(F->hasPersonalityFn(),
          "TerminatePadInst needs to be in a function with a personality.",

Modified: llvm/trunk/test/Feature/exception.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/exception.ll?rev=244563&r1=244562&r2=244563&view=diff
==============================================================================
--- llvm/trunk/test/Feature/exception.ll (original)
+++ llvm/trunk/test/Feature/exception.ll Mon Aug 10 21:48:30 2015
@@ -28,7 +28,11 @@ declare i32 @__gxx_personality_v0(...)
 
 define void @cleanupret0() personality i32 (...)* @__gxx_personality_v0 {
 entry:
-  br label %bb
+  br label %try.cont
+
+try.cont:
+  invoke void @_Z3quxv() optsize
+          to label %try.cont unwind label %bb
 bb:
   cleanuppad void [i7 4]
   cleanupret i8 0 unwind label %bb
@@ -36,7 +40,11 @@ bb:
 
 define void @cleanupret1() personality i32 (...)* @__gxx_personality_v0 {
 entry:
-  br label %bb
+  br label %try.cont
+
+try.cont:
+  invoke void @_Z3quxv() optsize
+          to label %try.cont unwind label %bb
 bb:
   cleanuppad void [i7 4]
   cleanupret void unwind label %bb
@@ -60,39 +68,69 @@ bb:
 
 define i8 @catchpad() personality i32 (...)* @__gxx_personality_v0 {
 entry:
-  br label %bb2
+  br label %try.cont
+
+try.cont:
+  invoke void @_Z3quxv() optsize
+          to label %bb unwind label %bb2
 bb:
-  ret i8 %cbv
+  ret i8 0
 bb2:
   %cbv = catchpad i8 [i7 4] to label %bb unwind label %bb2
 }
 
 define void @terminatepad0() personality i32 (...)* @__gxx_personality_v0 {
 entry:
-  br label %bb
+  br label %try.cont
+
+try.cont:
+  invoke void @_Z3quxv() optsize
+          to label %try.cont unwind label %bb
 bb:
   terminatepad [i7 4] unwind label %bb
 }
 
 define void @terminatepad1() personality i32 (...)* @__gxx_personality_v0 {
 entry:
+  br label %try.cont
+
+try.cont:
+  invoke void @_Z3quxv() optsize
+          to label %try.cont unwind label %bb
+bb:
   terminatepad [i7 4] unwind to caller
 }
 
 define void @cleanuppad() personality i32 (...)* @__gxx_personality_v0 {
 entry:
+  br label %try.cont
+
+try.cont:
+  invoke void @_Z3quxv() optsize
+          to label %try.cont unwind label %bb
+bb:
   cleanuppad void [i7 4]
   ret void
 }
 
 define void @catchendpad0() personality i32 (...)* @__gxx_personality_v0 {
 entry:
-  br label %bb
+  br label %try.cont
+
+try.cont:
+  invoke void @_Z3quxv() optsize
+          to label %try.cont unwind label %bb
 bb:
   catchendpad unwind label %bb
 }
 
 define void @catchendpad1() personality i32 (...)* @__gxx_personality_v0 {
 entry:
+  br label %try.cont
+
+try.cont:
+  invoke void @_Z3quxv() optsize
+          to label %try.cont unwind label %bb
+bb:
   catchendpad unwind to caller
 }




More information about the llvm-commits mailing list