aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CIR/CodeGen/delete.cpp
blob: f21d203f266e591b01c273efc6fd32f96cf1558b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -mconstructor-aliases -emit-cir %s -o %t.cir
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -mconstructor-aliases -emit-llvm %s -o %t-cir.ll
// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -mconstructor-aliases -emit-llvm %s -o %t.ll
// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s

typedef __typeof(sizeof(int)) size_t;

struct SizedDelete {
  void operator delete(void*, size_t);
  int member;
};
void test_sized_delete(SizedDelete *x) {
  delete x;
}

// SizedDelete::operator delete(void*, unsigned long)
// CIR:  cir.func private @_ZN11SizedDeletedlEPvm(!cir.ptr<!void>, !u64i)
// LLVM: declare void @_ZN11SizedDeletedlEPvm(ptr, i64)

// CIR: cir.func dso_local @_Z17test_sized_deleteP11SizedDelete
// CIR:   %[[X:.*]] = cir.load{{.*}} %{{.*}}
// CIR:   %[[X_CAST:.*]] = cir.cast(bitcast, %[[X]] : !cir.ptr<!rec_SizedDelete>), !cir.ptr<!void>
// CIR:   %[[OBJ_SIZE:.*]] = cir.const #cir.int<4> : !u64i
// CIR:   cir.call @_ZN11SizedDeletedlEPvm(%[[X_CAST]], %[[OBJ_SIZE]]) nothrow : (!cir.ptr<!void>, !u64i) -> ()

// LLVM: define dso_local void @_Z17test_sized_deleteP11SizedDelete
// LLVM:   %[[X:.*]] = load ptr, ptr %{{.*}}
// LLVM:   call void @_ZN11SizedDeletedlEPvm(ptr %[[X]], i64 4)

// OGCG: define dso_local void @_Z17test_sized_deleteP11SizedDelete
// OGCG:   %[[X:.*]] = load ptr, ptr %{{.*}}
// OGCG:   %[[ISNULL:.*]] = icmp eq ptr %[[X]], null
// OGCG:   br i1 %[[ISNULL]], label %{{.*}}, label %[[DELETE_NOTNULL:.*]]
// OGCG: [[DELETE_NOTNULL]]:
// OGCG:   call void @_ZN11SizedDeletedlEPvm(ptr noundef %[[X]], i64 noundef 4)

// This function is declared below the call in OGCG.
// OGCG: declare void @_ZN11SizedDeletedlEPvm(ptr noundef, i64 noundef)

struct Contents {
  ~Contents() {}
};
struct Container {
  Contents *contents;
  ~Container();
};
Container::~Container() { delete contents; }

// Contents::~Contents()
// CIR: cir.func comdat linkonce_odr @_ZN8ContentsD2Ev
// LLVM: define linkonce_odr void @_ZN8ContentsD2Ev

// operator delete(void*, unsigned long)
// CIR: cir.func private @_ZdlPvm(!cir.ptr<!void>, !u64i)
// LLVM: declare void @_ZdlPvm(ptr, i64)

// Container::~Container()
// CIR: cir.func dso_local @_ZN9ContainerD2Ev
// CIR:   %[[THIS:.*]] = cir.load %{{.*}}
// CIR:   %[[CONTENTS_PTR_ADDR:.*]] = cir.get_member %[[THIS]][0] {name = "contents"} : !cir.ptr<!rec_Container> -> !cir.ptr<!cir.ptr<!rec_Contents>>
// CIR:   %[[CONTENTS_PTR:.*]] = cir.load{{.*}} %[[CONTENTS_PTR_ADDR]]
// CIR:   cir.call @_ZN8ContentsD2Ev(%[[CONTENTS_PTR]]) nothrow : (!cir.ptr<!rec_Contents>) -> ()
// CIR:   %[[CONTENTS_CAST:.*]] = cir.cast(bitcast, %[[CONTENTS_PTR]] : !cir.ptr<!rec_Contents>), !cir.ptr<!void>
// CIR:   %[[OBJ_SIZE:.*]] = cir.const #cir.int<1> : !u64i
// CIR:   cir.call @_ZdlPvm(%[[CONTENTS_CAST]], %[[OBJ_SIZE]]) nothrow : (!cir.ptr<!void>, !u64i) -> ()

// LLVM: define dso_local void @_ZN9ContainerD2Ev
// LLVM:   %[[THIS:.*]] = load ptr, ptr %{{.*}}
// LLVM:   %[[CONTENTS_PTR_ADDR:.*]] = getelementptr %struct.Container, ptr %[[THIS]], i32 0, i32 0
// LLVM:   %[[CONTENTS_PTR:.*]] = load ptr, ptr %[[CONTENTS_PTR_ADDR]]
// LLVM:   call void @_ZN8ContentsD2Ev(ptr %[[CONTENTS_PTR]])
// LLVM:   call void @_ZdlPvm(ptr %[[CONTENTS_PTR]], i64 1)

// OGCG: define dso_local void @_ZN9ContainerD2Ev
// OGCG:   %[[THIS:.*]] = load ptr, ptr %{{.*}}
// OGCG:   %[[CONTENTS:.*]] = getelementptr inbounds nuw %struct.Container, ptr %[[THIS]], i32 0, i32 0
// OGCG:   %[[CONTENTS_PTR:.*]] = load ptr, ptr %[[CONTENTS]]
// OGCG:   %[[ISNULL:.*]] = icmp eq ptr %[[CONTENTS_PTR]], null
// OGCG:   br i1 %[[ISNULL]], label %{{.*}}, label %[[DELETE_NOTNULL:.*]]
// OGCG: [[DELETE_NOTNULL]]:
// OGCG:   call void @_ZN8ContentsD2Ev(ptr noundef nonnull align 1 dereferenceable(1) %[[CONTENTS_PTR]])
// OGCG:   call void @_ZdlPvm(ptr noundef %[[CONTENTS_PTR]], i64 noundef 1)

// These functions are declared/defined below the calls in OGCG.
// OGCG: define linkonce_odr void @_ZN8ContentsD2Ev
// OGCG: declare void @_ZdlPvm(ptr noundef, i64 noundef)