1 // XFAIL: * 2 3 // RUN: %clangxx_cfi -o %t1 %s 4 // RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s 5 6 // RUN: %clangxx_cfi -DB32 -o %t2 %s 7 // RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s 8 9 // RUN: %clangxx_cfi -DB64 -o %t3 %s 10 // RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s 11 12 // RUN: %clangxx_cfi -DBM -o %t4 %s 13 // RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s 14 15 // RUN: %clangxx -o %t5 %s 16 // RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s 17 18 // Tests that the CFI enforcement distinguishes betwen non-overriding siblings. 19 // XFAILed as not implemented yet. 20 21 #include <stdio.h> 22 #include "utils.h" 23 24 struct A { 25 virtual void f(); 26 }; 27 28 void A::f() {} 29 30 struct B : A { 31 virtual void f(); 32 }; 33 34 void B::f() {} 35 36 struct C : A { 37 }; 38 39 int main() { 40 create_derivers<B>(); 41 42 B *b = new B; 43 break_optimization(b); 44 45 // CFI: 1 46 // NCFI: 1 47 fprintf(stderr, "1\n"); 48 49 ((C *)b)->f(); // UB here 50 51 // CFI-NOT: 2 52 // NCFI: 2 53 fprintf(stderr, "2\n"); 54 } 55