cppeh-catch-intrinsics.ll 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. ; RUN: opt -lint -disable-output < %s 2>&1 | FileCheck %s
  2. ; This test is meant to prove that the Verifier is able to identify a variety
  3. ; of errors with the llvm.eh.begincatch and llvm.eh.endcatch intrinsics.
  4. ; See cppeh-catch-intrinsics-clean for correct uses.
  5. target triple = "x86_64-pc-windows-msvc"
  6. declare void @llvm.eh.begincatch(i8*, i8*)
  7. declare void @llvm.eh.endcatch()
  8. @_ZTIi = external constant i8*
  9. ; Function Attrs: uwtable
  10. define void @test_missing_endcatch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
  11. ; CHECK: Some paths from llvm.eh.begincatch may not reach llvm.eh.endcatch
  12. ; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn, i8* null)
  13. entry:
  14. invoke void @_Z9may_throwv()
  15. to label %try.cont unwind label %lpad
  16. lpad: ; preds = %entry
  17. %0 = landingpad { i8*, i32 }
  18. catch i8* bitcast (i8** @_ZTIi to i8*)
  19. %exn = extractvalue { i8*, i32 } %0, 0
  20. %sel = extractvalue { i8*, i32 } %0, 1
  21. %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
  22. %matches = icmp eq i32 %sel, %1
  23. br i1 %matches, label %catch, label %eh.resume
  24. catch: ; preds = %lpad
  25. call void @llvm.eh.begincatch(i8* %exn, i8* null)
  26. call void @_Z10handle_intv()
  27. br label %invoke.cont2
  28. invoke.cont2: ; preds = %catch
  29. br label %try.cont
  30. try.cont: ; preds = %invoke.cont2, %entry
  31. ret void
  32. eh.resume: ; preds = %catch.dispatch
  33. resume { i8*, i32 } %0
  34. }
  35. ; Function Attrs: uwtable
  36. define void @test_missing_begincatch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
  37. ; CHECK: llvm.eh.endcatch may be reachable without passing llvm.eh.begincatch
  38. ; CHECK-NEXT: call void @llvm.eh.endcatch()
  39. entry:
  40. invoke void @_Z9may_throwv()
  41. to label %try.cont unwind label %lpad
  42. lpad: ; preds = %entry
  43. %0 = landingpad { i8*, i32 }
  44. catch i8* bitcast (i8** @_ZTIi to i8*)
  45. %exn = extractvalue { i8*, i32 } %0, 0
  46. %sel = extractvalue { i8*, i32 } %0, 1
  47. %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
  48. %matches = icmp eq i32 %sel, %1
  49. br i1 %matches, label %catch, label %eh.resume
  50. catch: ; preds = %lpad
  51. call void @_Z10handle_intv()
  52. br label %invoke.cont2
  53. invoke.cont2: ; preds = %catch
  54. call void @llvm.eh.endcatch()
  55. br label %try.cont
  56. try.cont: ; preds = %invoke.cont2, %entry
  57. ret void
  58. eh.resume: ; preds = %catch.dispatch
  59. resume { i8*, i32 } %0
  60. }
  61. ; Function Attrs: uwtable
  62. define void @test_multiple_begin() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
  63. ; CHECK: llvm.eh.begincatch may be called a second time before llvm.eh.endcatch
  64. ; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn, i8* null)
  65. ; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn, i8* null)
  66. entry:
  67. invoke void @_Z9may_throwv()
  68. to label %try.cont unwind label %lpad
  69. lpad: ; preds = %entry
  70. %0 = landingpad { i8*, i32 }
  71. catch i8* bitcast (i8** @_ZTIi to i8*)
  72. %exn = extractvalue { i8*, i32 } %0, 0
  73. %sel = extractvalue { i8*, i32 } %0, 1
  74. %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
  75. %matches = icmp eq i32 %sel, %1
  76. br i1 %matches, label %catch, label %eh.resume
  77. catch: ; preds = %lpad
  78. call void @llvm.eh.begincatch(i8* %exn, i8* null)
  79. call void @_Z10handle_intv()
  80. br label %invoke.cont2
  81. invoke.cont2: ; preds = %catch
  82. call void @llvm.eh.begincatch(i8* %exn, i8* null)
  83. call void @llvm.eh.endcatch()
  84. br label %try.cont
  85. try.cont: ; preds = %invoke.cont2, %entry
  86. ret void
  87. eh.resume: ; preds = %catch.dispatch
  88. resume { i8*, i32 } %0
  89. }
  90. ; Function Attrs: uwtable
  91. define void @test_multiple_end() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
  92. ; CHECK: llvm.eh.endcatch may be called a second time after llvm.eh.begincatch
  93. ; CHECK-NEXT: call void @llvm.eh.endcatch()
  94. ; CHECK-NEXT: call void @llvm.eh.endcatch()
  95. entry:
  96. invoke void @_Z9may_throwv()
  97. to label %try.cont unwind label %lpad
  98. lpad: ; preds = %entry
  99. %0 = landingpad { i8*, i32 }
  100. catch i8* bitcast (i8** @_ZTIi to i8*)
  101. %exn = extractvalue { i8*, i32 } %0, 0
  102. %sel = extractvalue { i8*, i32 } %0, 1
  103. %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
  104. %matches = icmp eq i32 %sel, %1
  105. br i1 %matches, label %catch, label %eh.resume
  106. catch: ; preds = %lpad
  107. call void @llvm.eh.begincatch(i8* %exn, i8* null)
  108. call void @_Z10handle_intv()
  109. call void @llvm.eh.endcatch()
  110. br label %invoke.cont2
  111. invoke.cont2: ; preds = %catch
  112. call void @llvm.eh.endcatch()
  113. br label %try.cont
  114. try.cont: ; preds = %invoke.cont2, %entry
  115. ret void
  116. eh.resume: ; preds = %catch.dispatch
  117. resume { i8*, i32 } %0
  118. }
  119. ; Function Attrs: uwtable
  120. define void @test_begincatch_without_lpad() {
  121. ; CHECK: llvm.eh.begincatch may be reachable without passing a landingpad
  122. ; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn, i8* null)
  123. entry:
  124. %exn = alloca i8
  125. call void @llvm.eh.begincatch(i8* %exn, i8* null)
  126. call void @_Z10handle_intv()
  127. br label %invoke.cont2
  128. invoke.cont2: ; preds = %catch
  129. call void @llvm.eh.endcatch()
  130. br label %try.cont
  131. try.cont: ; preds = %invoke.cont2, %entry
  132. ret void
  133. }
  134. ; Function Attrs: uwtable
  135. define void @test_branch_to_begincatch_with_no_lpad(i32 %fake.sel) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
  136. ; CHECK: llvm.eh.begincatch may be reachable without passing a landingpad
  137. ; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn2, i8* null)
  138. entry:
  139. %fake.exn = alloca i8
  140. invoke void @_Z9may_throwv()
  141. to label %catch unwind label %lpad
  142. lpad: ; preds = %entry
  143. %0 = landingpad { i8*, i32 }
  144. catch i8* bitcast (i8** @_ZTIi to i8*)
  145. %exn = extractvalue { i8*, i32 } %0, 0
  146. %sel = extractvalue { i8*, i32 } %0, 1
  147. %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
  148. %matches = icmp eq i32 %sel, %1
  149. br i1 %matches, label %catch, label %eh.resume
  150. invoke void @_Z9may_throwv()
  151. to label %try.cont unwind label %lpad
  152. catch: ; preds = %lpad, %entry
  153. %exn2 = phi i8* [%exn, %lpad], [%fake.exn, %entry]
  154. %sel2 = phi i32 [%sel, %lpad], [%fake.sel, %entry]
  155. call void @llvm.eh.begincatch(i8* %exn2, i8* null)
  156. call void @_Z10handle_intv()
  157. %matches1 = icmp eq i32 %sel2, 0
  158. br i1 %matches1, label %invoke.cont2, label %invoke.cont3
  159. invoke.cont2: ; preds = %catch
  160. call void @llvm.eh.endcatch()
  161. br label %try.cont
  162. invoke.cont3: ; preds = %catch
  163. call void @llvm.eh.endcatch()
  164. br label %eh.resume
  165. try.cont: ; preds = %invoke.cont2
  166. ret void
  167. eh.resume: ; preds = %catch.dispatch
  168. %lpad.val = insertvalue { i8*, i32 } undef, i32 0, 1
  169. resume { i8*, i32 } %lpad.val
  170. }
  171. ; Function Attrs: uwtable
  172. define void @test_branch_missing_endcatch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
  173. ; CHECK: Some paths from llvm.eh.begincatch may not reach llvm.eh.endcatch
  174. ; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn2, i8* null)
  175. entry:
  176. invoke void @_Z9may_throwv()
  177. to label %invoke.cont unwind label %lpad
  178. invoke.cont:
  179. invoke void @_Z9may_throwv()
  180. to label %invoke.cont unwind label %lpad1
  181. lpad: ; preds = %entry
  182. %0 = landingpad { i8*, i32 }
  183. catch i8* bitcast (i8** @_ZTIi to i8*)
  184. %exn = extractvalue { i8*, i32 } %0, 0
  185. %sel = extractvalue { i8*, i32 } %0, 1
  186. %1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
  187. %matches = icmp eq i32 %sel, %1
  188. br i1 %matches, label %catch, label %eh.resume
  189. invoke void @_Z9may_throwv()
  190. to label %try.cont unwind label %lpad
  191. lpad1: ; preds = %entry
  192. %l1.0 = landingpad { i8*, i32 }
  193. cleanup
  194. catch i8* bitcast (i8** @_ZTIi to i8*)
  195. %exn1 = extractvalue { i8*, i32 } %l1.0, 0
  196. %sel1 = extractvalue { i8*, i32 } %l1.0, 1
  197. %l1.1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
  198. %matchesl1 = icmp eq i32 %sel1, %l1.1
  199. br i1 %matchesl1, label %catch, label %eh.resume
  200. catch: ; preds = %lpad, %lpad1
  201. %exn2 = phi i8* [%exn, %lpad], [%exn1, %lpad1]
  202. %sel2 = phi i32 [%sel, %lpad], [%sel1, %lpad1]
  203. call void @llvm.eh.begincatch(i8* %exn2, i8* null)
  204. call void @_Z10handle_intv()
  205. %matches1 = icmp eq i32 %sel2, 0
  206. br i1 %matches1, label %invoke.cont2, label %invoke.cont3
  207. invoke.cont2: ; preds = %catch
  208. call void @llvm.eh.endcatch()
  209. br label %try.cont
  210. invoke.cont3: ; preds = %catch
  211. br label %eh.resume
  212. try.cont: ; preds = %invoke.cont2, %entry
  213. ret void
  214. eh.resume: ; preds = %catch.dispatch
  215. %lpad.val = insertvalue { i8*, i32 } undef, i32 0, 1
  216. resume { i8*, i32 } %lpad.val
  217. }
  218. declare void @_Z9may_throwv()
  219. declare i32 @__CxxFrameHandler3(...)
  220. ; Function Attrs: nounwind readnone
  221. declare i32 @llvm.eh.typeid.for(i8*)
  222. declare void @_Z10handle_intv()