Home | History | Annotate | Download | only in CodeGenCXX
      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 
      5 extern "C" int basic_filter(int v, ...);
      6 extern "C" void might_crash();
      7 
      8 extern "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 
     34 struct S {
     35   int m1;
     36   void test_method(void);
     37 };
     38 
     39 void 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 
     60 void 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>@?0??test_lambda@@YAXXZ@QEBA@XZ"(%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>@?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>@?0??test_lambda@@YAXXZ@QEBA@XZ" to i8*), i8* %frame_pointer)
     80 // CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?0??test_lambda@@YAXXZ@QEBA@XZ" 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