1 // XFAIL: * 2 3 // RUN: %clangxx_cfi -o %t %s 4 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 5 6 // RUN: %clangxx_cfi -DB32 -o %t %s 7 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 8 9 // RUN: %clangxx_cfi -DB64 -o %t %s 10 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 11 12 // RUN: %clangxx_cfi -DBM -o %t %s 13 // RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s 14 15 // RUN: %clangxx -o %t %s 16 // RUN: %t 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 f()28void A::f() {} 29 30 struct B : A { 31 virtual void f(); 32 }; 33 f()34void B::f() {} 35 36 struct C : A { 37 }; 38 main()39int main() { 40 #ifdef B32 41 break_optimization(new Deriver<B, 0>); 42 #endif 43 44 #ifdef B64 45 break_optimization(new Deriver<B, 0>); 46 break_optimization(new Deriver<B, 1>); 47 #endif 48 49 #ifdef BM 50 break_optimization(new Deriver<B, 0>); 51 break_optimization(new Deriver<B, 1>); 52 break_optimization(new Deriver<B, 2>); 53 #endif 54 55 B *b = new B; 56 break_optimization(b); 57 58 // CFI: 1 59 // NCFI: 1 60 fprintf(stderr, "1\n"); 61 62 ((C *)b)->f(); // UB here 63 64 // CFI-NOT: 2 65 // NCFI: 2 66 fprintf(stderr, "2\n"); 67 } 68