// RUN: %clangxx_cfi -o %t %s // RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s // RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %clangxx_cfi -DB32 -o %t %s // RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s // RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %clangxx_cfi -DB64 -o %t %s // RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s // RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %clangxx_cfi -DBM -o %t %s // RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s // RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %clangxx_cfi -fsanitize=cfi-cast-strict -o %t %s // RUN: not --crash %t a 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t b 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t c 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t d 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t e 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t f 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t g 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: not --crash %t h 2>&1 | FileCheck --check-prefix=FAIL %s // RUN: %clangxx -o %t %s // RUN: %t a 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t b 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t c 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t d 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t e 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t f 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t g 2>&1 | FileCheck --check-prefix=PASS %s // RUN: %t h 2>&1 | FileCheck --check-prefix=PASS %s // Tests that the CFI enforcement detects bad casts. #include #include #include "utils.h" struct A { virtual void f(); }; void A::f() {} struct B : A { virtual void f(); }; void B::f() {} struct C : A { }; int main(int argc, char **argv) { #ifdef B32 break_optimization(new Deriver); #endif #ifdef B64 break_optimization(new Deriver); break_optimization(new Deriver); #endif #ifdef BM break_optimization(new Deriver); break_optimization(new Deriver); break_optimization(new Deriver); #endif B *b = new B; break_optimization(b); // FAIL: 1 // PASS: 1 fprintf(stderr, "1\n"); A a; switch (argv[1][0]) { case 'a': static_cast(&a); // UB break; case 'b': static_cast(a); // UB break; case 'c': static_cast(a); // UB break; case 'd': static_cast(&a); // UB, strict only break; case 'e': static_cast(a); // UB, strict only break; case 'f': static_cast(a); // UB, strict only break; case 'g': static_cast(static_cast(&a)); // Non-UB bad cast break; case 'h': static_cast(static_cast(&a)); // Non-UB bad cast, strict only break; } // FAIL-NOT: 2 // PASS: 2 fprintf(stderr, "2\n"); }