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