Skip to content

Instantly share code, notes, and snippets.

@thautwarm
Last active July 1, 2018 03:44
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 thautwarm/a499b2a0da6f9de0ccbe9780822c479f to your computer and use it in GitHub Desktop.
Save thautwarm/a499b2a0da6f9de0ccbe9780822c479f to your computer and use it in GitHub Desktop.
LLVM Exception handling
#include <stdio.h>
#include <stdlib.h>

class Object {
  public:
  virtual ~Object() {}
};

class Exception : public Object {
  public:
  Exception(const char* text)
      : _text(text)
  {
  }

  const char* GetText() const { return _text; }

  private:
  const char* _text;
};

#include <stdio.h>
#include <stdlib.h>

int main(){

	Exception exc = Exception("...");
	try{
		
		throw exc;
	}
	catch(Exception& e){
		printf("++");
	}
}
; ModuleID = 'cp.cpp'
source_filename = "cp.cpp"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

%class.Object = type { i32 (...)** }
%class.Exception = type { %class.Object, i8* }

$_ZN6ObjectD2Ev = comdat any

$_ZN9ExceptionD0Ev = comdat any

$_ZTS9Exception = comdat any

$_ZTS6Object = comdat any

$_ZTI6Object = comdat any

$_ZTI9Exception = comdat any

$_ZTV9Exception = comdat any

@.str = private unnamed_addr constant [4 x i8] c"...\00", align 1
@_ZTVN10__cxxabiv120__si_class_type_infoE = external global i8*
@_ZTS9Exception = linkonce_odr constant [11 x i8] c"9Exception\00", comdat
@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
@_ZTS6Object = linkonce_odr constant [8 x i8] c"6Object\00", comdat
@_ZTI6Object = linkonce_odr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @_ZTS6Object, i32 0, i32 0) }, comdat
@_ZTI9Exception = linkonce_odr constant { i8*, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @_ZTS9Exception, i32 0, i32 0), i8* bitcast ({ i8*, i8* }* @_ZTI6Object to i8*) }, comdat
@.str.1 = private unnamed_addr constant [3 x i8] c"++\00", align 1
@_ZTV9Exception = linkonce_odr unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI9Exception to i8*), i8* bitcast (void (%class.Object*)* @_ZN6ObjectD2Ev to i8*), i8* bitcast (void (%class.Exception*)* @_ZN9ExceptionD0Ev to i8*)] }, comdat, align 8

; Function Attrs: norecurse uwtable
define i32 @main() local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
  %1 = tail call i8* @__cxa_allocate_exception(i64 16) #6
  %2 = bitcast i8* %1 to i32 (...)***
  store i32 (...)** bitcast (i8** getelementptr inbounds ({ [4 x i8*] }, { [4 x i8*] }* @_ZTV9Exception, i64 0, inrange i32 0, i64 2) to i32 (...)**), i32 (...)*** %2, align 8, !tbaa !2
  %3 = getelementptr inbounds i8, i8* %1, i64 8
  %4 = bitcast i8* %3 to i64*
  store i64 ptrtoint ([4 x i8]* @.str to i64), i64* %4, align 8, !tbaa !5
  invoke void @__cxa_throw(i8* %1, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI9Exception to i8*), i8* bitcast (void (%class.Object*)* @_ZN6ObjectD2Ev to i8*)) #7
          to label %24 unwind label %5

; <label>:5:                                      ; preds = %0
  %6 = landingpad { i8*, i32 }
          cleanup
          catch i8* bitcast ({ i8*, i8*, i8* }* @_ZTI9Exception to i8*)
  %7 = extractvalue { i8*, i32 } %6, 0
  %8 = extractvalue { i8*, i32 } %6, 1
  %9 = tail call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8*, i8* }* @_ZTI9Exception to i8*)) #6
  %10 = icmp eq i32 %8, %9
  br i1 %10, label %11, label %19

; <label>:11:                                     ; preds = %5
  %12 = tail call i8* @__cxa_begin_catch(i8* %7) #6
  %13 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0))
  invoke void @__cxa_end_catch()
          to label %14 unwind label %15

; <label>:14:                                     ; preds = %11
  ret i32 0

; <label>:15:                                     ; preds = %11
  %16 = landingpad { i8*, i32 }
          cleanup
  %17 = extractvalue { i8*, i32 } %16, 1
  %18 = extractvalue { i8*, i32 } %16, 0
  br label %19

; <label>:19:                                     ; preds = %15, %5
  %20 = phi i32 [ %17, %15 ], [ %8, %5 ]
  %21 = phi i8* [ %18, %15 ], [ %7, %5 ]
  %22 = insertvalue { i8*, i32 } undef, i8* %21, 0
  %23 = insertvalue { i8*, i32 } %22, i32 %20, 1
  resume { i8*, i32 } %23

; <label>:24:                                     ; preds = %0
  unreachable
}

declare i8* @__cxa_allocate_exception(i64) local_unnamed_addr

; Function Attrs: norecurse nounwind uwtable
define linkonce_odr void @_ZN6ObjectD2Ev(%class.Object*) unnamed_addr #1 comdat align 2 {
  ret void
}

declare void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr

declare i32 @__gxx_personality_v0(...)

; Function Attrs: nounwind readnone
declare i32 @llvm.eh.typeid.for(i8*) #2

declare i8* @__cxa_begin_catch(i8*) local_unnamed_addr

; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr #3

declare void @__cxa_end_catch() local_unnamed_addr

; Function Attrs: inlinehint nounwind uwtable
define linkonce_odr void @_ZN9ExceptionD0Ev(%class.Exception*) unnamed_addr #4 comdat align 2 {
  %2 = bitcast %class.Exception* %0 to i8*
  tail call void @_ZdlPv(i8* %2) #8
  ret void
}

; Function Attrs: nobuiltin nounwind
declare void @_ZdlPv(i8*) local_unnamed_addr #5

attributes #0 = { norecurse uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { norecurse nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind readnone }
attributes #3 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #4 = { inlinehint nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #5 = { nobuiltin nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #6 = { nounwind }
attributes #7 = { noreturn }
attributes #8 = { builtin nounwind }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 6.0.1-svn333623-1~exp1~20180604222746.83 (branches/release_60)"}
!2 = !{!3, !3, i64 0}
!3 = !{!"vtable pointer", !4, i64 0}
!4 = !{!"Simple C++ TBAA"}
!5 = !{!6, !7, i64 8}
!6 = !{!"_ZTS9Exception", !7, i64 8}
!7 = !{!"any pointer", !8, i64 0}
!8 = !{!"omnipotent char", !4, i64 0}
@thautwarm
Copy link
Author

#include <stdio.h>

struct Ex{
	int x;
	int y;
	double z;
};

int main(){
	Ex e{1, 1, 1.0};
	try{
		throw e;
	}
	catch(Ex){
		printf("++");
	}
}
; ModuleID = 'cp.cpp'
source_filename = "cp.cpp"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"

%struct.Ex = type { i32, i32, double }

$_ZTS2Ex = comdat any

$_ZTI2Ex = comdat any

@_ZZ4mainE1e = private unnamed_addr constant %struct.Ex { i32 1, i32 1, double 1.000000e+00 }, align 8
@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
@_ZTS2Ex = linkonce_odr constant [4 x i8] c"2Ex\00", comdat
@_ZTI2Ex = linkonce_odr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_ZTS2Ex, i32 0, i32 0) }, comdat
@.str = private unnamed_addr constant [3 x i8] c"++\00", align 1

; Function Attrs: norecurse uwtable
define i32 @main() local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
  %1 = tail call i8* @__cxa_allocate_exception(i64 16) #4
  tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast (%struct.Ex* @_ZZ4mainE1e to i8*), i64 16, i32 8, i1 false), !tbaa.struct !2
  invoke void @__cxa_throw(i8* %1, i8* bitcast ({ i8*, i8* }* @_ZTI2Ex to i8*), i8* null) #5
          to label %12 unwind label %2

; <label>:2:                                      ; preds = %0
  %3 = landingpad { i8*, i32 }
          cleanup
          catch i8* bitcast ({ i8*, i8* }* @_ZTI2Ex to i8*)
  %4 = extractvalue { i8*, i32 } %3, 1
  %5 = tail call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI2Ex to i8*)) #4
  %6 = icmp eq i32 %4, %5
  br i1 %6, label %7, label %11

; <label>:7:                                      ; preds = %2
  %8 = extractvalue { i8*, i32 } %3, 0
  %9 = tail call i8* @__cxa_begin_catch(i8* %8) #4
  %10 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0))
  tail call void @__cxa_end_catch()
  ret i32 0

; <label>:11:                                     ; preds = %2
  resume { i8*, i32 } %3

; <label>:12:                                     ; preds = %0
  unreachable
}

; Function Attrs: argmemonly nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #1

declare i8* @__cxa_allocate_exception(i64) local_unnamed_addr

declare void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr

declare i32 @__gxx_personality_v0(...)

; Function Attrs: nounwind readnone
declare i32 @llvm.eh.typeid.for(i8*) #2

declare i8* @__cxa_begin_catch(i8*) local_unnamed_addr

; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr #3

declare void @__cxa_end_catch() local_unnamed_addr

attributes #0 = { norecurse uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { argmemonly nounwind }
attributes #2 = { nounwind readnone }
attributes #3 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #4 = { nounwind }
attributes #5 = { noreturn }

!llvm.module.flags = !{!0}
!llvm.ident = !{!1}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{!"clang version 6.0.1-svn333623-1~exp1~20180604222746.83 (branches/release_60)"}
!2 = !{i64 0, i64 4, !3, i64 4, i64 4, !3, i64 8, i64 8, !7}
!3 = !{!4, !4, i64 0}
!4 = !{!"int", !5, i64 0}
!5 = !{!"omnipotent char", !6, i64 0}
!6 = !{!"Simple C++ TBAA"}
!7 = !{!8, !8, i64 0}
!8 = !{!"double", !5, i64 0}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment