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