OSDN Git Service

[Verifier] Diagnose when unwinding out of cycles of blocks
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 1 Mar 2016 01:19:05 +0000 (01:19 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 1 Mar 2016 01:19:05 +0000 (01:19 +0000)
Generally speaking, this can only happen with unreachable code.
However, neglecting to check for this condition would lead us to loop
forever.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@262284 91177308-0d34-0410-b5e6-96231b3b80d8

lib/IR/Verifier.cpp
test/Verifier/invalid-eh.ll

index 8367a27..bea9b34 100644 (file)
@@ -3064,6 +3064,7 @@ void Verifier::visitEHPadPredecessors(Instruction &I) {
     }
 
     // The edge may exit from zero or more nested pads.
+    SmallSet<Value *, 8> Seen;
     for (;; FromPad = getParentPad(FromPad)) {
       Assert(FromPad != ToPad,
              "EH pad cannot handle exceptions raised within it", FromPad, TI);
@@ -3073,6 +3074,8 @@ void Verifier::visitEHPadPredecessors(Instruction &I) {
       }
       Assert(!isa<ConstantTokenNone>(FromPad),
              "A single unwind edge may only enter one EH pad", TI);
+      Assert(Seen.insert(FromPad).second,
+             "EH pad jumps through a cycle of pads", FromPad);
     }
   }
 }
@@ -3171,7 +3174,7 @@ void Verifier::visitFuncletPadInst(FuncletPadInst &FPI) {
   User *FirstUser = nullptr;
   Value *FirstUnwindPad = nullptr;
   SmallVector<FuncletPadInst *, 8> Worklist({&FPI});
-  std::set<FuncletPadInst *> Seen;
+  SmallSet<FuncletPadInst *, 8> Seen;
 
   while (!Worklist.empty()) {
     FuncletPadInst *CurrentPad = Worklist.pop_back_val();
index f94e3a6..e631715 100644 (file)
@@ -22,6 +22,7 @@
 ; RUN: sed -e s/.T22:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK22 %s
 ; RUN: sed -e s/.T23:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK23 %s
 ; RUN: sed -e s/.T24:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK24 %s
+; RUN: sed -e s/.T25:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK25 %s
 
 declare void @g()
 
@@ -420,3 +421,21 @@ declare void @g()
 ;T24: exit:
 ;T24:   unreachable
 ;T24: }
+
+;T25: define void @f() personality void ()* @g {
+;T25: entry:
+;T25:   unreachable
+;T25:
+;T25: catch.dispatch:
+;T25:   %cs = catchswitch within %cp2 [label %catch] unwind label %ehcleanup
+;T25:   ; CHECK25: EH pad jumps through a cycle of pads
+;T25:   ; CHECK25:   %cs = catchswitch within %cp2 [label %catch] unwind label %ehcleanup
+;T25:
+;T25: catch:
+;T25:   %cp2 = catchpad within %cs [i8* null, i32 64, i8* null]
+;T25:   unreachable
+;T25:
+;T25: ehcleanup:
+;T25:   %cp3 = cleanuppad within none []
+;T25:   cleanupret from %cp3 unwind to caller
+;T25: }