xref: /llvm-project/compiler-rt/test/cfi/multiple-inheritance.cpp (revision 3ccd23e1166ff7d79eb89579c0cd5056934a8f6c)
1702548d9SPeter Collingbourne // RUN: %clangxx_cfi -o %t1 %s
2*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t1 2>&1 | FileCheck --check-prefix=CFI %s
3*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t1 x 2>&1 | FileCheck --check-prefix=CFI %s
4e0c4f7ebSPeter Collingbourne 
5702548d9SPeter Collingbourne // RUN: %clangxx_cfi -DB32 -o %t2 %s
6*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t2 2>&1 | FileCheck --check-prefix=CFI %s
7*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t2 x 2>&1 | FileCheck --check-prefix=CFI %s
8f1d13da2SPeter Collingbourne 
9702548d9SPeter Collingbourne // RUN: %clangxx_cfi -DB64 -o %t3 %s
10*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t3 2>&1 | FileCheck --check-prefix=CFI %s
11*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t3 x 2>&1 | FileCheck --check-prefix=CFI %s
12f1d13da2SPeter Collingbourne 
13702548d9SPeter Collingbourne // RUN: %clangxx_cfi -DBM -o %t4 %s
14*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t4 2>&1 | FileCheck --check-prefix=CFI %s
15*3ccd23e1SFilipe Cabecinhas // RUN: %expect_crash %run %t4 x 2>&1 | FileCheck --check-prefix=CFI %s
16f1d13da2SPeter Collingbourne 
17702548d9SPeter Collingbourne // RUN: %clangxx -o %t5 %s
18*3ccd23e1SFilipe Cabecinhas // RUN: %run %t5 2>&1 | FileCheck --check-prefix=NCFI %s
19*3ccd23e1SFilipe Cabecinhas // RUN: %run %t5 x 2>&1 | FileCheck --check-prefix=NCFI %s
20e0c4f7ebSPeter Collingbourne 
21702548d9SPeter Collingbourne // RUN: %clangxx_cfi_diag -o %t6 %s
22*3ccd23e1SFilipe Cabecinhas // RUN: %run %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG2 %s
23*3ccd23e1SFilipe Cabecinhas // RUN: %run %t6 x 2>&1 | FileCheck --check-prefix=CFI-DIAG1 %s
24175d6332SPeter Collingbourne 
25e0c4f7ebSPeter Collingbourne // Tests that the CFI mechanism is sensitive to multiple inheritance and only
26e0c4f7ebSPeter Collingbourne // permits calls via virtual tables for the correct base class.
27e0c4f7ebSPeter Collingbourne 
28a084e16eSAlexey Samsonov // REQUIRES: cxxabi
29a084e16eSAlexey Samsonov 
30e0c4f7ebSPeter Collingbourne #include <stdio.h>
31f1d13da2SPeter Collingbourne #include "utils.h"
32e0c4f7ebSPeter Collingbourne 
33e0c4f7ebSPeter Collingbourne struct A {
34e0c4f7ebSPeter Collingbourne   virtual void f() = 0;
35e0c4f7ebSPeter Collingbourne };
36e0c4f7ebSPeter Collingbourne 
37e0c4f7ebSPeter Collingbourne struct B {
38e0c4f7ebSPeter Collingbourne   virtual void g() = 0;
39e0c4f7ebSPeter Collingbourne };
40e0c4f7ebSPeter Collingbourne 
41e0c4f7ebSPeter Collingbourne struct C : A, B {
42e0c4f7ebSPeter Collingbourne   virtual void f(), g();
43e0c4f7ebSPeter Collingbourne };
44e0c4f7ebSPeter Collingbourne 
f()45e0c4f7ebSPeter Collingbourne void C::f() {}
g()46e0c4f7ebSPeter Collingbourne void C::g() {}
47e0c4f7ebSPeter Collingbourne 
main(int argc,char ** argv)48e0c4f7ebSPeter Collingbourne int main(int argc, char **argv) {
49ea087056SPeter Collingbourne   create_derivers<A>();
50ea087056SPeter Collingbourne   create_derivers<B>();
51f1d13da2SPeter Collingbourne 
52e0c4f7ebSPeter Collingbourne   C *c = new C;
53f1d13da2SPeter Collingbourne   break_optimization(c);
54e0c4f7ebSPeter Collingbourne 
55e0c4f7ebSPeter Collingbourne   // CFI: 1
56e0c4f7ebSPeter Collingbourne   // NCFI: 1
57e0c4f7ebSPeter Collingbourne   fprintf(stderr, "1\n");
58e0c4f7ebSPeter Collingbourne 
59e0c4f7ebSPeter Collingbourne   if (argc > 1) {
60e0c4f7ebSPeter Collingbourne     A *a = c;
61175d6332SPeter Collingbourne     // CFI-DIAG1: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type
62702548d9SPeter Collingbourne     // CFI-DIAG1-NEXT: note: vtable is of type '{{(struct )?}}C'
63e0c4f7ebSPeter Collingbourne     ((B *)a)->g(); // UB here
64e0c4f7ebSPeter Collingbourne   } else {
65175d6332SPeter Collingbourne     // CFI-DIAG2: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type
66702548d9SPeter Collingbourne     // CFI-DIAG2-NEXT: note: vtable is of type '{{(struct )?}}C'
67e0c4f7ebSPeter Collingbourne     B *b = c;
68e0c4f7ebSPeter Collingbourne     ((A *)b)->f(); // UB here
69e0c4f7ebSPeter Collingbourne   }
70e0c4f7ebSPeter Collingbourne 
71702548d9SPeter Collingbourne   // CFI-NOT: {{^2$}}
72702548d9SPeter Collingbourne   // NCFI: {{^2$}}
73e0c4f7ebSPeter Collingbourne   fprintf(stderr, "2\n");
74e0c4f7ebSPeter Collingbourne }
75