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 3 4 extern "C" int basic_filter(int v, ...); 5 extern "C" void might_crash(); 6 7 extern "C" void test_freefunc(int p1) { 8 int l1 = 13; 9 static int s1 = 42; 10 __try { 11 might_crash(); 12 } __except(basic_filter(p1, l1, s1)) { 13 } 14 } 15 16 // CHECK-LABEL: define dso_local void @test_freefunc(i32 %p1) 17 // CHECK: @llvm.localescape(i32* %[[p1_ptr:[^, ]*]], i32* %[[l1_ptr:[^, ]*]]) 18 // CHECK: store i32 %p1, i32* %[[p1_ptr]], align 4 19 // CHECK: store i32 13, i32* %[[l1_ptr]], align 4 20 // CHECK: invoke void @might_crash() 21 22 // CHECK-LABEL: define internal i32 @"?filt$0@0@test_freefunc@@"(i8* %exception_pointers, i8* %frame_pointer) 23 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer) 24 // CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 0) 25 // CHECK: %[[p1_ptr:[^ ]*]] = bitcast i8* %[[p1_i8]] to i32* 26 // CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %[[fp]], i32 1) 27 // CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32* 28 // CHECK: %[[s1:[^ ]*]] = load i32, i32* @"?s1@?1??test_freefunc@@9@4HA", align 4 29 // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]] 30 // CHECK: %[[p1:[^ ]*]] = load i32, i32* %[[p1_ptr]] 31 // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[p1]], i32 %[[l1]], i32 %[[s1]]) 32 33 struct S { 34 int m1; 35 void test_method(void); 36 }; 37 38 void S::test_method() { 39 int l1 = 13; 40 __try { 41 might_crash(); 42 } __except(basic_filter(l1)) { 43 // FIXME: Test capturing 'this' and 'm1'. 44 } 45 } 46 47 // CHECK-LABEL: define dso_local void @"?test_method@S@@QEAAXXZ"(%struct.S* {{[^,]*}} %this) 48 // CHECK: @llvm.localescape(i32* %[[l1_addr:[^, ]*]]) 49 // CHECK: store i32 13, i32* %[[l1_addr]], align 4 50 // CHECK: invoke void @might_crash() 51 52 // CHECK-LABEL: define internal i32 @"?filt$0@0@test_method@S@@"(i8* %exception_pointers, i8* %frame_pointer) 53 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (%struct.S*)* @"?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer) 54 // CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%struct.S*)* @"?test_method@S@@QEAAXXZ" to i8*), i8* %[[fp]], i32 0) 55 // CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32* 56 // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]] 57 // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]]) 58 59 void test_lambda() { 60 int l1 = 13; 61 auto lambda = [&]() { 62 int l2 = 42; 63 __try { 64 might_crash(); 65 } __except(basic_filter(l2)) { 66 // FIXME: Test 'l1' when we can capture the lambda's 'this' decl. 67 } 68 }; 69 lambda(); 70 } 71 72 // CHECK-LABEL: define internal void @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ"(%class.anon* {{[^,]*}} %this) 73 // CHECK: @llvm.localescape(i32* %[[l2_addr:[^, ]*]]) 74 // CHECK: store i32 42, i32* %[[l2_addr]], align 4 75 // CHECK: invoke void @might_crash() 76 77 // CHECK-LABEL: define internal i32 @"?filt$0@0@?R<lambda_0>@?0??test_lambda@@YAXXZ@"(i8* %exception_pointers, i8* %frame_pointer) 78 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (%class.anon*)* @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %frame_pointer) 79 // CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %[[fp]], i32 0) 80 // CHECK: %[[l2_ptr:[^ ]*]] = bitcast i8* %[[l2_i8]] to i32* 81 // CHECK: %[[l2:[^ ]*]] = load i32, i32* %[[l2_ptr]] 82 // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l2]]) 83