diff options
author | Ivan Krasin <krasin@chromium.org> | 2015-09-30 23:08:55 +0000 |
---|---|---|
committer | Ivan Krasin <krasin@chromium.org> | 2015-09-30 23:08:55 +0000 |
commit | 8141b724aafb04141d6bdefb552e4340fe3fc805 (patch) | |
tree | 06ffe03affc5cc8ea2ff9b9f49e27343ab191db9 /test/cfi | |
parent | 47f7f79a6a70c89f88521c88a2b8164371faf719 (diff) |
CFI: add a test from base-to-derived cast from the base destructor.
Summary: This adds an interesting bad cast case, originally found in https://crbug.com/537398.
Reviewers: kcc
Subscribers: pcc
Differential Revision: http://reviews.llvm.org/D13307
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@248958 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/cfi')
-rw-r--r-- | test/cfi/base-derived-destructor.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/test/cfi/base-derived-destructor.cpp b/test/cfi/base-derived-destructor.cpp new file mode 100644 index 000000000..9655891ef --- /dev/null +++ b/test/cfi/base-derived-destructor.cpp @@ -0,0 +1,93 @@ +// RUN: %clangxx_cfi -o %t1 %s +// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DB32 -o %t2 %s +// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DB64 -o %t3 %s +// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DBM -o %t4 %s +// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O1 -o %t5 %s +// RUN: %expect_crash %t5 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O1 -DB32 -o %t6 %s +// RUN: %expect_crash %t6 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O1 -DB64 -o %t7 %s +// RUN: %expect_crash %t7 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O1 -DBM -o %t8 %s +// RUN: %expect_crash %t8 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O2 -o %t9 %s +// RUN: %expect_crash %t9 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O2 -DB32 -o %t10 %s +// RUN: %expect_crash %t10 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O2 -DB64 -o %t11 %s +// RUN: %expect_crash %t11 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O2 -DBM -o %t12 %s +// RUN: %expect_crash %t12 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O3 -o %t13 %s +// RUN: %expect_crash %t13 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O3 -DB32 -o %t14 %s +// RUN: %expect_crash %t14 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O3 -DB64 -o %t15 %s +// RUN: %expect_crash %t15 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -O3 -DBM -o %t16 %s +// RUN: %expect_crash %t16 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi_diag -o %t17 %s +// RUN: %t17 2>&1 | FileCheck --check-prefix=CFI-DIAG %s + +// RUN: %clangxx -o %t18 %s +// RUN: %t18 2>&1 | FileCheck --check-prefix=NCFI %s + +// Tests that the CFI mechanism crashes the program when making a +// base-to-derived cast from a destructor of the base class, +// where both types have virtual tables. + +// REQUIRES: cxxabi + +#include <stdio.h> +#include "utils.h" + +template<typename T> +class A { + public: + T* context() { return static_cast<T*>(this); } + + virtual ~A() { + break_optimization(context()); + } +}; + +class B : public A<B> { + public: + virtual ~B() { } +}; + +int main() { + // CFI: 1 + // NCFI: 1 + fprintf(stderr, "1\n"); + + // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast + // CFI-DIAG-NEXT: note: vtable is of type 'A<B>' + B* b = new B; + break_optimization(b); + delete b; // UB here + + // CFI-NOT: {{^2$}} + // NCFI: {{^2$}} + fprintf(stderr, "2\n"); +} |