61 lines · cpp
1// RUN: %clangxx_cfi_diag -o %t %s2// RUN: %run %t 2>&1 | FileCheck %s3 4// This test checks that we don't generate two type checks,5// if two virtual calls are in the same function.6 7// UNSUPPORTED: target={{.*windows-msvc.*}}8// REQUIRES: cxxabi9 10// TODO(krasin): implement the optimization to not emit two type checks.11// XFAIL: *12#include <stdio.h>13 14class Base {15 public:16 virtual void Foo() {17 fprintf(stderr, "Base::Foo\n");18 }19 20 virtual void Bar() {21 fprintf(stderr, "Base::Bar\n");22 }23};24 25class Derived : public Base {26 public:27 void Foo() override {28 fprintf(stderr, "Derived::Foo\n");29 }30 31 void Bar() override {32 printf("Derived::Bar\n");33 }34};35 36__attribute__((noinline)) void print(Base* ptr) {37 ptr->Foo();38 // Corrupt the vtable pointer. We expect that the optimization will39 // check vtable before the first vcall then store it in a local40 // 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();44}45 46 47int main() {48 Base b;49 Derived d;50 // CHECK: Base::Foo51 // CHECK: Base::Bar52 print(&b);53 54 // CHECK: Derived::Foo55 // CHECK-NOT: runtime error56 // CHECK: Derived::Bar57 print(&d);58 59 return 0;60}61