|
| 1 | +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-cir %s -o %t.cir |
| 2 | +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s |
| 3 | + |
| 4 | +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-llvm %s -o %t.cir |
| 5 | +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.cir %s |
| 6 | + |
| 7 | +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -emit-llvm %s -o %t.cir |
| 8 | +// RUN: FileCheck --check-prefix=OGCG --input-file=%t.cir %s |
| 9 | + |
| 10 | +class A { |
| 11 | + virtual ~A(); |
| 12 | + A B(A); |
| 13 | +}; |
| 14 | +A A::B(A) { |
| 15 | + // CIR-LABEL: cir.func dso_local @_ZN1A1BES_( |
| 16 | + // CIR-SAME: %[[THIS_ARG:.*]]: !cir.ptr<!rec_A> |
| 17 | + // CIR-NEXT: %[[THIS_VAR:.*]] = cir.alloca !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>> |
| 18 | + // CIR: cir.store %[[THIS_ARG]], %[[THIS_VAR]] : !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>> |
| 19 | + // CIR: %[[THIS:.*]] = cir.load %[[THIS_VAR]] : !cir.ptr<!cir.ptr<!rec_A>>, !cir.ptr<!rec_A> |
| 20 | + // CIR-NEXT: %[[VPTR_PTR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_A> -> !cir.ptr<!cir.vptr> |
| 21 | + // CIR-NEXT: %[[VPTR:.*]] = cir.load align(8) %[[VPTR_PTR]] : !cir.ptr<!cir.vptr>, !cir.vptr |
| 22 | + // CIR-NEXT: %[[DTOR_PTR:.*]] = cir.vtable.get_virtual_fn_addr %[[VPTR]][0] : !cir.vptr -> !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>> |
| 23 | + // CIR-NEXT: %[[DTOR:.*]] = cir.load align(8) %[[DTOR_PTR]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>>, !cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>> |
| 24 | + // CIR-NEXT: cir.call %[[DTOR]](%[[THIS]]) : (!cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>, !cir.ptr<!rec_A>) -> () |
| 25 | + // CIR-NEXT: cir.trap |
| 26 | + // CIR-NEXT: } |
| 27 | + |
| 28 | + |
| 29 | + // LLVM-LABEL: define dso_local %class.A @_ZN1A1BES_( |
| 30 | + // LLVM-SAME: ptr %[[THIS_ARG:[0-9]+]], |
| 31 | + // LLVM-NEXT: %[[THIS_VAR:.*]] = alloca ptr, i64 1, align 8 |
| 32 | + // LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_VAR]], align 8 |
| 33 | + // LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_VAR]], align 8 |
| 34 | + // LLVM-NEXT: %[[VTABLE_PTR:.*]] = load ptr, ptr %[[THIS]], align 8 |
| 35 | + // LLVM-NEXT: %[[VIRT_DTOR_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE_PTR]], i32 0 |
| 36 | + // LLVM-NEXT: %[[DTOR:.*]] = load ptr, ptr %[[VIRT_DTOR_ADDR]], align 8 |
| 37 | + // LLVM-NEXT: call void %[[DTOR]](ptr %[[THIS]]) |
| 38 | + // LLVM-NEXT: call void @llvm.trap() |
| 39 | + // LLVM-NEXT: unreachable |
| 40 | + // LLVM-NEXT: } |
| 41 | + |
| 42 | + |
| 43 | + // OGCG-LABEL: define dso_local void @_ZN1A1BES_( |
| 44 | + // OGCG-SAME: ptr {{.*}}%[[THIS_ARG:.*]], |
| 45 | + // OGCG: %[[VAL_0:.*]] = alloca ptr, align 8 |
| 46 | + // OGCG-NEXT: %[[THIS_VAR:.*]] = alloca ptr, align 8 |
| 47 | + // OGCG: store ptr %[[THIS_ARG]], ptr %[[THIS_VAR]], align 8 |
| 48 | + // OGCG: %[[THIS:.*]] = load ptr, ptr %[[THIS_VAR]], align 8 |
| 49 | + // OGCG-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[THIS]], align 8 |
| 50 | + // OGCG-NEXT: %[[VIRT_DTOR_ADDR:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE]], i64 0 |
| 51 | + // OGCG-NEXT: %[[DTOR:.*]] = load ptr, ptr %[[VIRT_DTOR_ADDR]], align 8 |
| 52 | + // OGCG-NEXT: call void %[[DTOR]](ptr noundef nonnull align 8 dereferenceable(8) %[[THIS]]) #2 |
| 53 | + // OGCG-NEXT: call void @llvm.trap() |
| 54 | + // OGCG-NEXT: unreachable |
| 55 | + // OGCG-NEXT: } |
| 56 | + |
| 57 | + this->~A(); |
| 58 | +} |
0 commit comments