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 Collingbournevoid C::f() {} g()46e0c4f7ebSPeter Collingbournevoid C::g() {} 47e0c4f7ebSPeter Collingbourne main(int argc,char ** argv)48e0c4f7ebSPeter Collingbourneint 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