Skip to content

Instantly share code, notes, and snippets.

@ytomino
Created May 11, 2011 20:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ytomino/967290 to your computer and use it in GitHub Desktop.
Save ytomino/967290 to your computer and use it in GitHub Desktop.
LLVM exception test with libstdc++
; llvm-as c++exn.ll && llvm-ld -native c++exn.bc -lstdc++.6 && ./a.out
; LLVM primitives
declare i8* @llvm.eh.exception() nounwind readonly
declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
declare i32 @llvm.eh.typeid.for(i8*) nounwind
; libc
declare i32 @puts(i8*)
; libgcc
declare void @_Unwind_Resume_or_Rethrow(i8*)
; libstdc++
declare i32 @__gxx_personality_v0(...)
declare i8* @__cxa_allocate_exception(i32)
declare void @__cxa_throw(i8*, i8*, i8*)
declare i8* @__cxa_begin_catch(i8*)
declare void @__cxa_end_catch()
@_ZTIi = external constant i8* ; typeinfo(int)
@_ZTIf = external constant i8* ; typeinfo(float)
@str0 = private constant [4 x i8] c"int\00"
@str1 = private constant [6 x i8] c"float\00"
define i32 @main() {
%reraising_exn = alloca i8*
%raising_exn = call i8* @__cxa_allocate_exception(i32 4) nounwind
%raising_exn.ptr = bitcast i8* %raising_exn to i32*
store i32 0, i32* %raising_exn.ptr
invoke void @__cxa_throw(i8* %raising_exn, i8* bitcast (i8** @_ZTIi to i8*), i8* null) noreturn
to label %after_try
unwind label %begin_catch
begin_catch:
%exn = call i8* @llvm.eh.exception() nounwind
store i8* %exn, i8** %reraising_exn
%sel = call i32 (i8*, i8*, ...)* @llvm.eh.selector(
i8* %exn,
i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*),
i8* bitcast (i8** @_ZTIi to i8*),
i8* bitcast (i8** @_ZTIf to i8*),
i8* null) nounwind
br label %when_int
when_int:
%eh.int.typeid = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind
%eh.int.comp = icmp eq i32 %sel, %eh.int.typeid
br i1 %eh.int.comp, label %catch_int, label %when_float
catch_int:
%eh.int.obj = call i8* @__cxa_begin_catch(i8* %exn) nounwind
%eh.int.ptr = bitcast i8* %eh.int.obj to i32*
%eh.int.val = load i32* %eh.int.ptr
invoke i32 @puts(i8* getelementptr inbounds ([4 x i8]* @str0, i32 0, i32 0))
to label %end_catch
unwind label %raise_another
when_float:
%eh.float.typeid = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIf to i8*)) nounwind
%eh.float.comp = icmp eq i32 %sel, %eh.float.typeid
br i1 %eh.float.comp, label %catch_float, label %reraising
catch_float:
%eh.float.obj = call i8* @__cxa_begin_catch(i8* %exn) nounwind
%eh.float.ptr = bitcast i8* %eh.float.obj to float*
%eh.float.val = load float* %eh.float.ptr
invoke i32 @puts(i8* getelementptr inbounds ([6 x i8]* @str1, i32 0, i32 0))
to label %end_catch
unwind label %raise_another
end_catch:
call void @__cxa_end_catch() nounwind
br label %after_try
raise_another:
%ra.exn = call i8* @llvm.eh.exception() nounwind
store i8* %ra.exn, i8** %reraising_exn
%ra.sel = call i32 (i8*, i8*, ...)* @llvm.eh.selector(
i8* %ra.exn,
i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*),
i8* null) nounwind
call void @__cxa_end_catch() nounwind
br label %reraising
reraising:
%reraising_exn.val = load i8** %reraising_exn
call void @_Unwind_Resume_or_Rethrow(i8* %reraising_exn.val) noreturn
unreachable
after_try: ; after try-catch statement
ret i32 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment