1 | // RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions | FileCheck %s |
2 | // RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions -DSTD | FileCheck %s |
3 | |
4 | // CHECK-DAG: @"??_R0?AUY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUY@@\00" }, comdat |
5 | // CHECK-DAG: @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUY@@@8" to i8*), i32 0, i32 -1, i32 0, i32 8, i8* bitcast (%struct.Y* (%struct.Y*, %struct.Y*, i32)* @"??0Y@@QAE@ABU0@@Z" to i8*) }, section ".xdata", comdat |
6 | // CHECK-DAG: @"??_R0?AUZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUZ@@\00" }, comdat |
7 | // CHECK-DAG: @"_CT??_R0?AUZ@@@81" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUZ@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* null }, section ".xdata", comdat |
8 | // CHECK-DAG: @"??_R0?AUW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUW@@\00" }, comdat |
9 | // CHECK-DAG: @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUW@@@8" to i8*), i32 4, i32 -1, i32 0, i32 4, i8* bitcast (%struct.W* (%struct.W*, %struct.W*, i32)* @"??0W@@QAE@ABU0@@Z" to i8*) }, section ".xdata", comdat |
10 | // CHECK-DAG: @"??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }, comdat |
11 | // CHECK-DAG: @"_CT??_R0?AUM@@@818" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUM@@@8" to i8*), i32 8, i32 -1, i32 0, i32 1, i8* null }, section ".xdata", comdat |
12 | // CHECK-DAG: @"??_R0?AUV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"??_7type_info@@6B@", i8* null, [8 x i8] c".?AUV@@\00" }, comdat |
13 | // CHECK-DAG: @"_CT??_R0?AUV@@@81044" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i32 0, i32 4, i32 4, i32 1, i8* null }, section ".xdata", comdat |
14 | // CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8", %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44", %eh.CatchableType* @"_CT??_R0?AUM@@@818", %eh.CatchableType* @"_CT??_R0?AUV@@@81044"] }, section ".xdata", comdat |
15 | // CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"??_DY@@QAEXXZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat |
16 | // CHECK-DAG: @"_CT??_R0?AUDefault@@@8??_ODefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor13* @"??_R0?AUDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Default*, %struct.Default*)* @"??_ODefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat |
17 | // CHECK-DAG: @"_CT??_R0?AUVariadic@@@8??_OVariadic@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor14* @"??_R0?AUVariadic@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Variadic*, %struct.Variadic*)* @"??_OVariadic@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat |
18 | // CHECK-DAG: @"_CT??_R0?AUTemplateWithDefault@@@8??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor25* @"??_R0?AUTemplateWithDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.TemplateWithDefault*, %struct.TemplateWithDefault*)* @"??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat |
19 | // CHECK-DAG: @"_CTA2$$T" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0$$T@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat |
20 | // CHECK-DAG: @"_CT??_R0P6AXXZ@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0P6AXXZ@8" to i8*), i32 0, i32 -1, i32 0, i32 4, i8* null }, section ".xdata", comdat |
21 | // CHECK-DAG: @_CTA1P6AXXZ = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0P6AXXZ@84"] }, section ".xdata", comdat |
22 | // CHECK-DAG: @_TI1P6AXXZ = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1P6AXXZ to i8*) }, section ".xdata", comdat |
23 | // CHECK-DAG: @_TIU2PAPFAH = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 4, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.2* @_CTA2PAPFAH to i8*) }, section ".xdata", comdat |
24 | // CHECK-DAG: @_CTA2PAPFAH = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0PAPFAH@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat |
25 | // CHECK-DAG: @"_TI1?AUFoo@?A0x{{[^@]*}}@@" = internal unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @"_CTA1?AUFoo@?A0x{{[^@]*}}@@" to i8*) }, section ".xdata" |
26 | |
27 | |
28 | struct N { ~N(); }; |
29 | struct M : private N {}; |
30 | struct X {}; |
31 | struct Z {}; |
32 | struct V : private X {}; |
33 | struct W : M, virtual V {}; |
34 | struct Y : Z, W, virtual V {}; |
35 | |
36 | void f(const Y &y) { |
37 | // CHECK-LABEL: @"?f@@YAXABUY@@@Z" |
38 | // CHECK: call x86_thiscallcc %struct.Y* @"??0Y@@QAE@ABU0@@Z"(%struct.Y* %[[mem:.*]], %struct.Y* |
39 | // CHECK: %[[cast:.*]] = bitcast %struct.Y* %[[mem]] to i8* |
40 | // CHECK: call void @_CxxThrowException(i8* %[[cast]], %eh.ThrowInfo* @"_TI5?AUY@@") |
41 | throw y; |
42 | } |
43 | |
44 | void g(const int *const *y) { |
45 | // CHECK-LABEL: @"?g@@YAXPBQBH@Z" |
46 | // CHECK: call void @_CxxThrowException(i8* %{{.*}}, %eh.ThrowInfo* @_TIC2PAPBH) |
47 | throw y; |
48 | } |
49 | |
50 | void h(__unaligned int * __unaligned *y) { |
51 | // CHECK-LABEL: @"?h@@YAXPFAPFAH@Z" |
52 | // CHECK: call void @_CxxThrowException(i8* %{{.*}}, %eh.ThrowInfo* @_TIU2PAPFAH) |
53 | throw y; |
54 | } |
55 | |
56 | struct Default { |
57 | Default(Default &, int = 42); |
58 | }; |
59 | |
60 | // CHECK-LABEL: @"??_ODefault@@QAEXAAU0@@Z" |
61 | // CHECK: %[[src_addr:.*]] = alloca |
62 | // CHECK: %[[this_addr:.*]] = alloca |
63 | // CHECK: store {{.*}} %src, {{.*}} %[[src_addr]], align 4 |
64 | // CHECK: store {{.*}} %this, {{.*}} %[[this_addr]], align 4 |
65 | // CHECK: %[[this:.*]] = load {{.*}} %[[this_addr]] |
66 | // CHECK: %[[src:.*]] = load {{.*}} %[[src_addr]] |
67 | // CHECK: call x86_thiscallcc {{.*}} @"??0Default@@QAE@AAU0@H@Z"({{.*}} %[[this]], {{.*}} %[[src]], i32 42) |
68 | // CHECK: ret void |
69 | |
70 | void h(Default &d) { |
71 | throw d; |
72 | } |
73 | |
74 | struct Variadic { |
75 | Variadic(Variadic &, ...); |
76 | }; |
77 | |
78 | void i(Variadic &v) { |
79 | throw v; |
80 | } |
81 | |
82 | // CHECK-LABEL: @"??_OVariadic@@QAEXAAU0@@Z" |
83 | // CHECK: %[[src_addr:.*]] = alloca |
84 | // CHECK: %[[this_addr:.*]] = alloca |
85 | // CHECK: store {{.*}} %src, {{.*}} %[[src_addr:.*]], align |
86 | // CHECK: store {{.*}} %this, {{.*}} %[[this_addr:.*]], align |
87 | // CHECK: %[[this:.*]] = load {{.*}} %[[this_addr]] |
88 | // CHECK: %[[src:.*]] = load {{.*}} %[[src_addr]] |
89 | // CHECK: call {{.*}} @"??0Variadic@@QAA@AAU0@ZZ"({{.*}} %[[this]], {{.*}} %[[src]]) |
90 | // CHECK: ret void |
91 | |
92 | struct TemplateWithDefault { |
93 | template <typename T> |
94 | static int f() { |
95 | return 0; |
96 | } |
97 | template <typename T = int> |
98 | TemplateWithDefault(TemplateWithDefault &, T = f<T>()); |
99 | }; |
100 | |
101 | void j(TemplateWithDefault &twd) { |
102 | throw twd; |
103 | } |
104 | |
105 | |
106 | void h() { |
107 | throw nullptr; |
108 | } |
109 | |
110 | #ifdef STD |
111 | namespace std { |
112 | template <typename T> |
113 | void *__GetExceptionInfo(T); |
114 | } |
115 | #else |
116 | template <typename T> |
117 | void *__GetExceptionInfo(T); |
118 | #endif |
119 | using namespace std; |
120 | |
121 | void *GetExceptionInfo_test0() { |
122 | // CHECK-LABEL: @"?GetExceptionInfo_test0@@YAPAXXZ" |
123 | // CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1H to i8*) |
124 | return __GetExceptionInfo(0); |
125 | } |
126 | |
127 | void *GetExceptionInfo_test1() { |
128 | // CHECK-LABEL: @"?GetExceptionInfo_test1@@YAPAXXZ" |
129 | // CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1P6AXXZ to i8*) |
130 | return __GetExceptionInfo<void (*)()>(&h); |
131 | } |
132 | |
133 | // PR36327: Try an exception type with no linkage. |
134 | namespace { struct Foo { } foo_exc; } |
135 | |
136 | void *GetExceptionInfo_test2() { |
137 | // CHECK-LABEL: @"?GetExceptionInfo_test2@@YAPAXXZ" |
138 | // CHECK: ret i8* bitcast (%eh.ThrowInfo* @"_TI1?AUFoo@?A0x{{[^@]*}}@@" to i8*) |
139 | return __GetExceptionInfo(foo_exc); |
140 | } |
141 | |