98 lines · cpp
1// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-cir %s -o %t.cir2// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s3// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-llvm %s -o %t-cir.ll4// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s5// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-llvm %s -o %t.ll6// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s7 8class A {9 int a;10};11 12class B {13 int b;14public:15 A *getAsA();16};17 18class X : public A, public B {19 int x;20};21 22X *castAtoX(A *a) {23 return static_cast<X*>(a);24}25 26// CIR: cir.func {{.*}} @_Z8castAtoXP1A(%[[ARG0:.*]]: !cir.ptr<!rec_A> {{.*}})27// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>>, ["a", init]28// CIR: cir.store %[[ARG0]], %[[A_ADDR]] : !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>>29// CIR: %[[A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!cir.ptr<!rec_A>>, !cir.ptr<!rec_A>30// CIR: %[[X:.*]] = cir.derived_class_addr %[[A]] : !cir.ptr<!rec_A> [0] -> !cir.ptr<!rec_X>31 32// Note: Because the offset is 0, a null check is not needed.33 34// LLVM: define {{.*}} ptr @_Z8castAtoXP1A(ptr %[[ARG0:.*]])35// LLVM: %[[A_ADDR:.*]] = alloca ptr36// LLVM: store ptr %[[ARG0]], ptr %[[A_ADDR]]37// LLVM: %[[X:.*]] = load ptr, ptr %[[A_ADDR]]38 39// OGCG: define {{.*}} ptr @_Z8castAtoXP1A(ptr {{.*}} %[[ARG0:.*]])40// OGCG: %[[A_ADDR:.*]] = alloca ptr41// OGCG: store ptr %[[ARG0]], ptr %[[A_ADDR]]42// OGCG: %[[X:.*]] = load ptr, ptr %[[A_ADDR]]43 44X *castBtoX(B *b) {45 return static_cast<X*>(b);46}47 48// CIR: cir.func {{.*}} @_Z8castBtoXP1B(%[[ARG0:.*]]: !cir.ptr<!rec_B> {{.*}})49// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.ptr<!rec_B>, !cir.ptr<!cir.ptr<!rec_B>>, ["b", init]50// CIR: cir.store %[[ARG0]], %[[B_ADDR]] : !cir.ptr<!rec_B>, !cir.ptr<!cir.ptr<!rec_B>>51// CIR: %[[B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.ptr<!rec_B>>, !cir.ptr<!rec_B>52// CIR: %[[X:.*]] = cir.derived_class_addr %[[B]] : !cir.ptr<!rec_B> [4] -> !cir.ptr<!rec_X>53 54// LLVM: define {{.*}} ptr @_Z8castBtoXP1B(ptr %[[ARG0:.*]])55// LLVM: %[[B_ADDR:.*]] = alloca ptr, i64 1, align 856// LLVM: store ptr %[[ARG0]], ptr %[[B_ADDR]], align 857// LLVM: %[[B:.*]] = load ptr, ptr %[[B_ADDR]], align 858// LLVM: %[[IS_NULL:.*]] = icmp eq ptr %[[B]], null59// LLVM: %[[B_NON_NULL:.*]] = getelementptr inbounds i8, ptr %[[B]], i32 -460// LLVM: %[[X:.*]] = select i1 %[[IS_NULL]], ptr %[[B]], ptr %[[B_NON_NULL]]61 62// OGCG: define {{.*}} ptr @_Z8castBtoXP1B(ptr {{.*}} %[[ARG0:.*]])63// OGCG: entry:64// OGCG: %[[B_ADDR:.*]] = alloca ptr65// OGCG: store ptr %[[ARG0]], ptr %[[B_ADDR]]66// OGCG: %[[B:.*]] = load ptr, ptr %[[B_ADDR]]67// OGCG: %[[IS_NULL:.*]] = icmp eq ptr %[[B]], null68// OGCG: br i1 %[[IS_NULL]], label %[[LABEL_NULL:.*]], label %[[LABEL_NOTNULL:.*]]69// OGCG: [[LABEL_NOTNULL]]:70// OGCG: %[[B_NON_NULL:.*]] = getelementptr inbounds i8, ptr %[[B]], i64 -471// OGCG: br label %[[LABEL_END:.*]]72// OGCG: [[LABEL_NULL]]:73// OGCG: br label %[[LABEL_END:.*]]74// OGCG: [[LABEL_END]]:75// OGCG: %[[X:.*]] = phi ptr [ %[[B_NON_NULL]], %[[LABEL_NOTNULL]] ], [ null, %[[LABEL_NULL]] ]76 77X &castBReftoXRef(B &b) {78 return static_cast<X&>(b);79}80 81// CIR: cir.func {{.*}} @_Z14castBReftoXRefR1B(%[[ARG0:.*]]: !cir.ptr<!rec_B> {{.*}})82// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.ptr<!rec_B>, !cir.ptr<!cir.ptr<!rec_B>>, ["b", init, const]83// CIR: cir.store %[[ARG0]], %[[B_ADDR]] : !cir.ptr<!rec_B>, !cir.ptr<!cir.ptr<!rec_B>>84// CIR: %[[B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!cir.ptr<!rec_B>>, !cir.ptr<!rec_B>85// CIR: %[[X:.*]] = cir.derived_class_addr %[[B]] : !cir.ptr<!rec_B> nonnull [4] -> !cir.ptr<!rec_X>86 87// LLVM: define {{.*}} ptr @_Z14castBReftoXRefR1B(ptr %[[ARG0:.*]])88// LLVM: %[[B_ADDR:.*]] = alloca ptr89// LLVM: store ptr %[[ARG0]], ptr %[[B_ADDR]]90// LLVM: %[[B:.*]] = load ptr, ptr %[[B_ADDR]]91// LLVM: %[[X:.*]] = getelementptr inbounds i8, ptr %[[B]], i32 -492 93// OGCG: define {{.*}} ptr @_Z14castBReftoXRefR1B(ptr {{.*}} %[[ARG0:.*]])94// OGCG: %[[B_ADDR:.*]] = alloca ptr95// OGCG: store ptr %[[ARG0]], ptr %[[B_ADDR]]96// OGCG: %[[B:.*]] = load ptr, ptr %[[B_ADDR]]97// OGCG: %[[X:.*]] = getelementptr inbounds i8, ptr %[[B]], i64 -498