1 // RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-nvcall -emit-llvm -o - %s | FileCheck %s 2 // RUN: %clang_cc1 -triple x86_64-unknown-linux -fvisibility hidden -fsanitize=cfi-nvcall,cfi-cast-strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-STRICT %s 3 4 struct A { 5 virtual void f(); 6 }; 7 8 struct B : A { 9 int i; 10 void g(); 11 }; 12 13 struct C : A { 14 void g(); 15 }; 16 17 // CHECK-LABEL: @bg 18 // CHECK-STRICT-LABEL: @bg 19 extern "C" void bg(B *b) { 20 // CHECK: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B") 21 // CHECK-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B") 22 b->g(); 23 } 24 25 // CHECK-LABEL: @cg 26 // CHECK-STRICT-LABEL: @cg 27 extern "C" void cg(C *c) { 28 // http://clang.llvm.org/docs/ControlFlowIntegrity.html#strictness 29 // In this case C's layout is the same as its base class, so we allow 30 // c to be of type A in non-strict mode. 31 32 // CHECK: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1A") 33 // CHECK-STRICT: call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1C") 34 c->g(); 35 } 36