brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.7 KiB · 588d808 Raw
128 lines · cpp
1// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - -O1 -disable-llvm-passes | FileCheck %s --implicit-check-not='call {{.*}} @__dynamic_cast'2struct Offset { virtual ~Offset(); };3struct A { virtual ~A(); };4struct B final : Offset, A { };5 6struct C { virtual ~C(); int c; };7struct D : A { int d; };8struct E : A { int e; };9struct F : virtual A { int f; };10struct G : virtual A { int g; };11struct H final : C, D, E, F, G { int h; };12struct H1 final: C, private D { int h1; };13 14// CHECK-LABEL: @_Z7inexactP1A15C *inexact(A *a) {16  // CHECK: call {{.*}} @__dynamic_cast17  return dynamic_cast<C*>(a);18}19 20// CHECK-LABEL: @_Z12exact_singleP1A21B *exact_single(A *a) {22  // CHECK: %[[PTR_NULL:.*]] = icmp eq ptr %[[PTR:.*]], null23  // CHECK: br i1 %[[PTR_NULL]], label %[[LABEL_FAILED:.*]], label %[[LABEL_NOTNULL:.*]]24 25  // CHECK: [[LABEL_NOTNULL]]:26  // CHECK: %[[VPTR:.*]] = load ptr, ptr %[[PTR]]27  // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[VPTR]], getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr @_ZTV1B, i32 0, i32 1, i32 2)28  // CHECK: %[[RESULT:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i64 -829  // CHECK: br i1 %[[MATCH]], label %[[LABEL_END:.*]], label %[[LABEL_FAILED]]30 31  // CHECK: [[LABEL_FAILED]]:32  // CHECK: br label %[[LABEL_END]]33 34  // CHECK: [[LABEL_END]]:35  // CHECK: phi ptr [ %[[RESULT]], %[[LABEL_NOTNULL]] ], [ null, %[[LABEL_FAILED]] ]36  return dynamic_cast<B*>(a);37}38 39// CHECK-LABEL: @_Z9exact_refR1A40B &exact_ref(A &a) {41  // CHECK: %[[PTR_NULL:.*]] = icmp eq ptr %[[PTR:.*]], null42  // CHECK: br i1 %[[PTR_NULL]], label %[[LABEL_FAILED:.*]], label %[[LABEL_NOTNULL:.*]]43 44  // CHECK: [[LABEL_NOTNULL]]:45  // CHECK: %[[VPTR:.*]] = load ptr, ptr %[[PTR]]46  // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[VPTR]], getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr @_ZTV1B, i32 0, i32 1, i32 2)47  // CHECK: %[[RESULT:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i64 -848  // CHECK: br i1 %[[MATCH]], label %[[LABEL_END:.*]], label %[[LABEL_FAILED]]49 50  // CHECK: [[LABEL_FAILED]]:51  // CHECK: call {{.*}} @__cxa_bad_cast52  // CHECK: unreachable53 54  // CHECK: [[LABEL_END]]:55  // CHECK: ret ptr %[[RESULT]]56  return dynamic_cast<B&>(a);57}58 59// CHECK-LABEL: @_Z11exact_multiP1A60H *exact_multi(A *a) {61  // CHECK: %[[PTR_NULL:.*]] = icmp eq ptr %[[PTR:.*]], null62  // CHECK: br i1 %[[PTR_NULL]], label %[[LABEL_FAILED:.*]], label %[[LABEL_NOTNULL:.*]]63 64  // CHECK: [[LABEL_NOTNULL]]:65  // CHECK: %[[VPTR:.*]] = load ptr, ptr %[[PTR]]66  // CHECK: %[[OFFSET_TO_TOP_SLOT:.*]] = getelementptr inbounds i64, ptr %[[VPTR]], i64 -267  // CHECK: %[[OFFSET_TO_TOP:.*]] = load i64, ptr %[[OFFSET_TO_TOP_SLOT]]68  // CHECK: %[[RESULT:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i64 %[[OFFSET_TO_TOP]]69  // CHECK: %[[DERIVED_VPTR:.*]] = load ptr, ptr %[[RESULT]]70  // CHECK: %[[MATCH:.*]] = icmp eq ptr %[[DERIVED_VPTR]], getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [4 x ptr], [4 x ptr], [6 x ptr], [6 x ptr] }, ptr @_ZTV1H, i32 0, i32 0, i32 3)71  // CHECK: br i1 %[[MATCH]], label %[[LABEL_END:.*]], label %[[LABEL_FAILED]]72 73  // CHECK: [[LABEL_FAILED]]:74  // CHECK: br label %[[LABEL_END]]75 76  // CHECK: [[LABEL_END]]:77  // CHECK: phi ptr [ %[[RESULT]], %[[LABEL_NOTNULL]] ], [ null, %[[LABEL_FAILED]] ]78  return dynamic_cast<H*>(a);79}80 81// CHECK-LABEL: @_Z19exact_invalid_multiP1D82H1 *exact_invalid_multi(D* d) {83  // CHECK:      entry:84  // CHECK-NEXT:   %d.addr = alloca ptr85  // CHECK-NEXT:   store ptr %d, ptr %d.addr86  // CHECK-NEXT:   load ptr, ptr %d.addr87  // CHECK-NEXT:   ret ptr null88  return dynamic_cast<H1*>(d);89}90 91// CHECK-LABEL: @_Z19exact_invalid_multiR1D92H1 &exact_invalid_multi(D& d) {93  // CHECK:      entry:94  // CHECK-NEXT:   %d.addr = alloca ptr95  // CHECK-NEXT:   store ptr %d, ptr %d.addr96  // CHECK-NEXT:   load ptr, ptr %d.addr97  // CHECK-NEXT:   call void @__cxa_bad_cast()98  // CHECK-NEXT:   unreachable99  // CHECK:      dynamic_cast.unreachable:100  // CHECK-NEXT:   ret ptr poison101  return dynamic_cast<H1&>(d);102}103 104namespace GH137518 {105  class base { virtual void fn() = 0; };106  class test final : base { virtual void fn() { } };107  test* new_test() { return new test(); }108 109  // CHECK-LABEL: @_ZN8GH1375184castEPNS_4baseE(110  test* cast(base* b) {111    // CHECK:      entry:112    // CHECK-NEXT:   %b.addr = alloca ptr113    // CHECK-NEXT:   store ptr %b, ptr %b.addr114    // CHECK-NEXT:   load ptr, ptr %b.addr115    // CHECK-NEXT:   ret ptr null116    return dynamic_cast<test*>(b);117  }118}119 120namespace GH64088 {121  // Ensure we mark the B vtable as used here, because we're going to emit a122  // reference to it.123  // CHECK: define {{.*}} void @_ZN7GH640881BD0Ev(124  struct A { virtual ~A(); };125  struct B final : A { virtual ~B() = default; };126  B *cast(A *p) { return dynamic_cast<B*>(p); }127}128