1 // RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \
2 // RUN: -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | FileCheck %s
4 extern "C" int basic_filter(int v
, ...);
5 extern "C" void might_crash();
7 extern "C" void test_freefunc(int p1
) {
12 } __except(basic_filter(p1
, l1
, s1
)) {
16 // CHECK-LABEL: define dso_local void @test_freefunc(i32 noundef %p1)
17 // CHECK: @llvm.localescape(ptr %[[p1_ptr:[^, ]*]], ptr %[[l1_ptr:[^, ]*]])
18 // CHECK: store i32 %p1, ptr %[[p1_ptr]], align 4
19 // CHECK: store i32 13, ptr %[[l1_ptr]], align 4
20 // CHECK: invoke void @might_crash()
22 // CHECK-LABEL: define internal noundef i32 @"?filt$0@0@test_freefunc@@"(ptr noundef %exception_pointers, ptr noundef %frame_pointer)
23 // CHECK: %[[fp:[^ ]*]] = call ptr @llvm.eh.recoverfp(ptr @test_freefunc, ptr %frame_pointer)
24 // CHECK: %[[p1_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @test_freefunc, ptr %[[fp]], i32 0)
25 // CHECK: %[[l1_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @test_freefunc, ptr %[[fp]], i32 1)
26 // CHECK: %[[s1:[^ ]*]] = load i32, ptr @"?s1@?1??test_freefunc@@9@4HA", align 4
27 // CHECK: %[[l1:[^ ]*]] = load i32, ptr %[[l1_i8]]
28 // CHECK: %[[p1:[^ ]*]] = load i32, ptr %[[p1_i8]]
29 // CHECK: call i32 (i32, ...) @basic_filter(i32 noundef %[[p1]], i32 noundef %[[l1]], i32 noundef %[[s1]])
33 void test_method(void);
36 void S::test_method() {
40 } __except (basic_filter(l1
, m1
)) {
44 // CHECK-LABEL: define dso_local void @"?test_method@S@@QEAAXXZ"(ptr {{[^,]*}} %this)
45 // CHECK: @llvm.localescape(ptr %[[l1_addr:[^, ]*]], ptr %[[this_addr:[^, ]*]])
46 // CHECK: store ptr %this, ptr %[[this_addr]], align 8
47 // CHECK: store i32 13, ptr %[[l1_addr]], align 4
48 // CHECK: invoke void @might_crash()
50 // CHECK-LABEL: define internal noundef i32 @"?filt$0@0@test_method@S@@"(ptr noundef %exception_pointers, ptr noundef %frame_pointer)
51 // CHECK: %[[fp:[^ ]*]] = call ptr @llvm.eh.recoverfp(ptr @"?test_method@S@@QEAAXXZ", ptr %frame_pointer)
52 // CHECK: %[[l1_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"?test_method@S@@QEAAXXZ", ptr %[[fp]], i32 0)
53 // CHECK: %[[this_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"?test_method@S@@QEAAXXZ", ptr %[[fp]], i32 1)
54 // CHECK: %[[this:[^ ]*]] = load ptr, ptr %[[this_i8]], align 8
55 // CHECK: %[[m1_ptr:[^ ]*]] = getelementptr inbounds %struct.S, ptr %[[this]], i32 0, i32 0
56 // CHECK: %[[m1:[^ ]*]] = load i32, ptr %[[m1_ptr]]
57 // CHECK: %[[l1:[^ ]*]] = load i32, ptr %[[l1_i8]]
58 // CHECK: call i32 (i32, ...) @basic_filter(i32 noundef %[[l1]], i32 noundef %[[m1]])
61 void test_virtual(int p1
);
62 virtual void virt(int p1
);
65 void V::test_virtual(int p1
) {
73 // CHECK-LABEL: define dso_local void @"?test_virtual@V@@QEAAXH@Z"(ptr {{[^,]*}} %this, i32 noundef %p1)
74 // CHECK: @llvm.localescape(ptr %[[this_addr:[^, ]*]], ptr %[[p1_addr:[^, ]*]])
75 // CHECK: store i32 %p1, ptr %[[p1_addr]], align 4
76 // CHECK: store ptr %this, ptr %[[this_addr]], align 8
77 // CHECK: invoke void @might_crash()
79 // CHECK-LABEL: define internal void @"?fin$0@0@test_virtual@V@@"(i8 noundef %abnormal_termination, ptr noundef %frame_pointer)
80 // CHECK: %[[this_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"?test_virtual@V@@QEAAXH@Z", ptr %frame_pointer, i32 0)
81 // CHECK: %[[this:[^ ]*]] = load ptr, ptr %[[this_i8]], align 8
82 // CHECK: %[[p1_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"?test_virtual@V@@QEAAXH@Z", ptr %frame_pointer, i32 1)
83 // CHECK: %[[p1:[^ ]*]] = load i32, ptr %[[p1_i8]]
84 // CHECK: %[[vtable:[^ ]*]] = load ptr, ptr %[[this]], align 8
85 // CHECK: %[[vfn:[^ ]*]] = getelementptr inbounds ptr, ptr %[[vtable]], i64 0
86 // CHECK: %[[virt:[^ ]*]] = load ptr, ptr %[[vfn]], align 8
87 // CHECK: call void %[[virt]](ptr {{[^,]*}} %[[this]], i32 noundef %[[p1]])
95 } __except (basic_filter(l1
, l2
)) {
101 // CHECK-LABEL: define internal void @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ"(ptr {{[^,]*}} %this)
102 // CHECK: @llvm.localescape(ptr %[[this_addr:[^, ]*]], ptr %[[l2_addr:[^, ]*]])
103 // CHECK: store ptr %this, ptr %[[this_addr]], align 8
104 // CHECK: store i32 42, ptr %[[l2_addr]], align 4
105 // CHECK: invoke void @might_crash()
107 // CHECK-LABEL: define internal noundef i32 @"?filt$0@0@?R<lambda_0>@?0??test_lambda@@YAXXZ@"(ptr noundef %exception_pointers, ptr noundef %frame_pointer)
108 // CHECK: %[[fp:[^ ]*]] = call ptr @llvm.eh.recoverfp(ptr @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ", ptr %frame_pointer)
109 // CHECK: %[[this_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ", ptr %[[fp]], i32 0)
110 // CHECK: %[[this:[^ ]*]] = load ptr, ptr %[[this_i8]], align 8
111 // CHECK: %[[l2_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ", ptr %[[fp]], i32 1)
112 // CHECK: %[[l2:[^ ]*]] = load i32, ptr %[[l2_i8]]
113 // CHECK: %[[l1_ref_ptr:[^ ]*]] = getelementptr inbounds %class.anon, ptr %[[this]], i32 0, i32 0
114 // CHECK: %[[l1_ref:[^ ]*]] = load ptr, ptr %[[l1_ref_ptr]]
115 // CHECK: %[[l1:[^ ]*]] = load i32, ptr %[[l1_ref]]
116 // CHECK: call i32 (i32, ...) @basic_filter(i32 noundef %[[l1]], i32 noundef %[[l2]])
119 void this_in_lambda();
122 void U::this_in_lambda() {
123 auto lambda
= [=]() {
126 } __except (basic_filter(0, this)) {
132 // CHECK-LABEL: define internal noundef i32 @"?filt$0@0@?R<lambda_1>@?0??this_in_lambda@U@@QEAAXXZ@"(ptr noundef %exception_pointers, ptr noundef %frame_pointer)
133 // CHECK: %[[this_i8:[^ ]*]] = call ptr @llvm.localrecover(ptr @"??R<lambda_1>@?0??this_in_lambda@U@@QEAAXXZ@QEBA@XZ", ptr %[[fp:[^ ]*]], i32 0)
134 // CHECK: %[[this:[^ ]*]] = load ptr, ptr %[[this_i8]], align 8
135 // CHECK: %[[actual_this_ptr:[^ ]*]] = getelementptr inbounds %class.anon.0, ptr %[[this]], i32 0, i32 0
136 // CHECK: %[[actual_this:[^ ]*]] = load ptr, ptr %[[actual_this_ptr]], align 8
137 // CHECK: call i32 (i32, ...) @basic_filter(i32 noundef 0, ptr noundef %[[actual_this]])