Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / compiler-rt / test / cfi / two-vcalls.cpp
blob019214d59a45f3bc9205243efa1827e3a5013070
1 // RUN: %clangxx_cfi_diag -o %t %s
2 // RUN: %run %t 2>&1 | FileCheck %s
4 // This test checks that we don't generate two type checks,
5 // if two virtual calls are in the same function.
7 // UNSUPPORTED: target={{.*windows-msvc.*}}
8 // REQUIRES: cxxabi
10 // TODO(krasin): implement the optimization to not emit two type checks.
11 // XFAIL: *
12 #include <stdio.h>
14 class Base {
15 public:
16 virtual void Foo() {
17 fprintf(stderr, "Base::Foo\n");
20 virtual void Bar() {
21 fprintf(stderr, "Base::Bar\n");
25 class Derived : public Base {
26 public:
27 void Foo() override {
28 fprintf(stderr, "Derived::Foo\n");
31 void Bar() override {
32 printf("Derived::Bar\n");
36 __attribute__((noinline)) void print(Base* ptr) {
37 ptr->Foo();
38 // Corrupt the vtable pointer. We expect that the optimization will
39 // check vtable before the first vcall then store it in a local
40 // variable, and reuse it for the second vcall. With no optimization,
41 // CFI will complain about the virtual table being corrupted.
42 *reinterpret_cast<void**>(ptr) = 0;
43 ptr->Bar();
47 int main() {
48 Base b;
49 Derived d;
50 // CHECK: Base::Foo
51 // CHECK: Base::Bar
52 print(&b);
54 // CHECK: Derived::Foo
55 // CHECK-NOT: runtime error
56 // CHECK: Derived::Bar
57 print(&d);
59 return 0;