1 // RUN: %clang_cc1 -triple %ms_abi_triple -fms-extensions -std=c++11 -emit-llvm -O2 -o - %s | FileCheck %s 2 3 void target_func(); 4 void (*func_ptr)() = &target_func; 5 6 // The "guard_nocf" attribute must be added. nocf0()7__declspec(guard(nocf)) void nocf0() { 8 (*func_ptr)(); 9 } 10 // CHECK-LABEL: nocf0 11 // CHECK: call{{.*}}[[NOCF:#[0-9]+]] 12 13 // The "guard_nocf" attribute must *not* be added. cf0()14void cf0() { 15 (*func_ptr)(); 16 } 17 // CHECK-LABEL: cf0 18 // CHECK: call{{.*}}[[CF:#[0-9]+]] 19 20 // If the modifier is present on either the function declaration or definition, 21 // the "guard_nocf" attribute must be added. 22 __declspec(guard(nocf)) void nocf1(); nocf1()23void nocf1() { 24 (*func_ptr)(); 25 } 26 // CHECK-LABEL: nocf1 27 // CHECK: call{{.*}}[[NOCF:#[0-9]+]] 28 29 void nocf2(); nocf2()30__declspec(guard(nocf)) void nocf2() { 31 (*func_ptr)(); 32 } 33 // CHECK-LABEL: nocf2 34 // CHECK: call{{.*}}[[NOCF:#[0-9]+]] 35 36 // When inlining a function, the "guard_nocf" attribute on indirect calls must 37 // be preserved. nocf3()38void nocf3() { 39 nocf0(); 40 } 41 // CHECK-LABEL: nocf3 42 // CHECK: call{{.*}}[[NOCF:#[0-9]+]] 43 44 // When inlining into a function marked as __declspec(guard(nocf)), the 45 // "guard_nocf" attribute must *not* be added to the inlined calls. cf1()46__declspec(guard(nocf)) void cf1() { 47 cf0(); 48 } 49 // CHECK-LABEL: cf1 50 // CHECK: call{{.*}}[[CF:#[0-9]+]] 51 52 // When the __declspec(guard(nocf)) modifier is present on an override function, 53 // the "guard_nocf" attribute must be added. 54 struct Base { 55 virtual void nocf4(); 56 }; 57 58 struct Derived : Base { nocf4Derived59 __declspec(guard(nocf)) void nocf4() override { 60 (*func_ptr)(); 61 } 62 }; 63 Derived d; 64 // CHECK-LABEL: nocf4 65 // CHECK: call{{.*}}[[NOCF:#[0-9]+]] 66 67 // When the modifier is not present on an override function, the "guard_nocf" 68 // attribute must *not* be added, even if the modifier is present on the virtual 69 // function. 70 struct Base1 { 71 __declspec(guard(nocf)) virtual void cf2(); 72 }; 73 74 struct Derived1 : Base1 { cf2Derived175 void cf2() override { 76 (*func_ptr)(); 77 } 78 }; 79 Derived1 d1; 80 // CHECK-LABEL: cf2 81 // CHECK: call{{.*}}[[CF:#[0-9]+]] 82 83 // CHECK: attributes [[NOCF]] = { {{.*}}"guard_nocf"{{.*}} } 84 // CHECK-NOT: attributes [[CF]] = { {{.*}}"guard_nocf"{{.*}} } 85