51 lines · cpp
1// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s2// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 -fno-delete-null-pointer-checks | FileCheck %s3 4struct Left {5 virtual void left();6};7 8struct Right {9 virtual void right();10};11 12struct ChildNoOverride : Left, Right {13};14 15struct ChildOverride : Left, Right {16 virtual void left();17 virtual void right();18};19 20extern "C" void foo(void *);21 22void call_left_no_override(ChildNoOverride *child) {23 // CHECK: %[[CHILD:.*]] = load ptr24 child->left();25}26 27void ChildOverride::left() {}28 29void call_right_no_override(ChildNoOverride *child) {30 child->right();31 // When calling a right base's virtual method, one needs to adjust `this` at the caller site.32 //33 // CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8, ptr %[[CHILD]], i32 434 //35 // CHECK: %[[VFTABLE:.*]] = load ptr, ptr %[[RIGHT_i8]]36 // CHECK: %[[VFUN:.*]] = getelementptr inbounds ptr, ptr %[[VFTABLE]], i64 037}38 39void ChildOverride::right() {40 foo(this);41}42 43void call_right_override(ChildOverride *child) {44 child->right();45 // Ensure that `nonnull` and `dereferenceable(N)` are not emitted whether or not null is valid46 //47 // CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8, ptr %[[CHILD]], i32 448 // CHECK: %[[VFUN_VALUE:.*]] = load ptr, ptr %[[VFUN]]49 // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](ptr noundef %[[RIGHT]])50}51