<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Jun 29, 2015 at 10:10 AM, Dmitry Vyukov <span dir="ltr"><<a href="mailto:dvyukov@google.com" target="_blank">dvyukov@google.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
The inner catch should have a resume, but control still does not leave the function.</blockquote><div><br></div><div>In what sense do you mean control does not leave the function? This is the -O2 IR for that function:</div><div><br></div><div><div>define void @_Z3foov() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {</div><div>entry:</div><div>  invoke void @_Z3barv()</div><div>          to label %try.cont.6 unwind label %lpad</div><div>lpad:                                             ; preds = %entry</div><div>  %0 = landingpad { i8*, i32 }</div><div>          catch i8* bitcast (i8** @_ZTId to i8*)</div><div>          catch i8* bitcast (i8** @_ZTIi to i8*)</div><div>  %1 = extractvalue { i8*, i32 } %0, 0</div><div>  %2 = extractvalue { i8*, i32 } %0, 1</div><div>  %3 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTId to i8*)) #3</div><div>  %matches = icmp eq i32 %2, %3</div><div>  br i1 %matches, label %catch, label %catch.dispatch.1</div><div>catch.dispatch.1:                                 ; preds = %lpad</div><div>  %4 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #3</div><div>  %matches3 = icmp eq i32 %2, %4</div><div>  br i1 %matches3, label %catch.4, label %eh.resume</div><div>catch.4:                                          ; preds = %catch.dispatch.1</div><div>  %5 = tail call i8* @__cxa_begin_catch(i8* %1) #3</div><div>  tail call void @__cxa_end_catch() #3</div><div>  br label %try.cont.6</div><div>try.cont.6:                                       ; preds = %catch, %entry, %catch.4</div><div>  ret void</div><div>catch:                                            ; preds = %lpad</div><div>  %6 = tail call i8* @__cxa_begin_catch(i8* %1) #3</div><div>  tail call void @__cxa_end_catch() #3</div><div>  br label %try.cont.6</div><div>eh.resume:                                        ; preds = %catch.dispatch.1</div><div>  resume { i8*, i32 } %0</div><div>}</div></div><div><br></div><div>Semantically, in LLVM, control is always considered to transfer to the landingpad when an exception is thrown, even if it is not one of the listed types. The EH dispatch that checks for typeid double and typeid int is still there, and if it fails, control continues to 'resume'. The clauses of the landingpad are more like an optimization that allows the runtime to bypass landingpads that are known to be no-ops. Your pass is inserting cleanup code, so it needs to add the 'cleanup' bit to landingpads like this one to ensure that the runtime hits bar's lpad regardless of the exception type.</div><div><br></div><div>The main reason for these semantics is to keep the logic for inlining simple. When inlining through an 'invoke', the inliner more or less transforms 'ret's into branches to the normal successor and 'resume's into branches to the exceptional successor. landingpad clauses also have to be combined.</div></div></div></div>