[PATCH] tsan: support C++ exceptions

Reid Kleckner rnk at google.com
Mon Jun 29 10:38:44 PDT 2015


On Mon, Jun 29, 2015 at 10:10 AM, Dmitry Vyukov <dvyukov at google.com> wrote:
>
> The inner catch should have a resume, but control still does not leave the
> function.


In what sense do you mean control does not leave the function? This is the
-O2 IR for that function:

define void @_Z3foov() #0 personality i8* bitcast (i32 (...)*
@__gxx_personality_v0 to i8*) {
entry:
  invoke void @_Z3barv()
          to label %try.cont.6 unwind label %lpad
lpad:                                             ; preds = %entry
  %0 = landingpad { i8*, i32 }
          catch i8* bitcast (i8** @_ZTId to i8*)
          catch i8* bitcast (i8** @_ZTIi to i8*)
  %1 = extractvalue { i8*, i32 } %0, 0
  %2 = extractvalue { i8*, i32 } %0, 1
  %3 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTId to i8*))
#3
  %matches = icmp eq i32 %2, %3
  br i1 %matches, label %catch, label %catch.dispatch.1
catch.dispatch.1:                                 ; preds = %lpad
  %4 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
#3
  %matches3 = icmp eq i32 %2, %4
  br i1 %matches3, label %catch.4, label %eh.resume
catch.4:                                          ; preds =
%catch.dispatch.1
  %5 = tail call i8* @__cxa_begin_catch(i8* %1) #3
  tail call void @__cxa_end_catch() #3
  br label %try.cont.6
try.cont.6:                                       ; preds = %catch, %entry,
%catch.4
  ret void
catch:                                            ; preds = %lpad
  %6 = tail call i8* @__cxa_begin_catch(i8* %1) #3
  tail call void @__cxa_end_catch() #3
  br label %try.cont.6
eh.resume:                                        ; preds =
%catch.dispatch.1
  resume { i8*, i32 } %0
}

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.

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150629/e7219fc4/attachment.html>


More information about the llvm-commits mailing list