@@ -35,6 +35,10 @@ void operator delete(void *p) { i-=2; }
35
35
void operator delete[] (void *p) { i--; }
36
36
};
37
37
38
+ struct AllocatedAsArray : public Bird {
39
+
40
+ };
41
+
38
42
// Vector deleting dtor for Bird is an alias because no new Bird[] expressions
39
43
// in the TU.
40
44
// X64: @"??_EBird@@UEAAPEAXI@Z" = weak dso_local unnamed_addr alias ptr (ptr, i32), ptr @"??_GBird@@UEAAPEAXI@Z"
@@ -55,6 +59,14 @@ Bird* alloc() {
55
59
return P;
56
60
}
57
61
62
+
63
+ template <class C >
64
+ struct S {
65
+ void foo () { void *p = new C (); delete (C *)p; }
66
+ };
67
+
68
+ S<AllocatedAsArray[1 ][3 ]> sp;
69
+
58
70
void bar () {
59
71
dealloc (alloc ());
60
72
@@ -63,6 +75,8 @@ void bar() {
63
75
64
76
Bird *p = new HasOperatorDelete[2 ];
65
77
dealloc (p);
78
+
79
+ sp.foo ();
66
80
}
67
81
68
82
// CHECK-LABEL: define dso_local void @{{.*}}dealloc{{.*}}(
@@ -99,6 +113,36 @@ void bar() {
99
113
// CHECK: delete.end:
100
114
// CHECK-NEXT: ret void
101
115
116
+ // Definition of S::foo, check that it has vector deleting destructor call
117
+ // X64-LABEL: define linkonce_odr dso_local void @"?foo@?$S@$$BY102UAllocatedAsArray@@@@QEAAXXZ"
118
+ // X86-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?foo@?$S@$$BY102UAllocatedAsArray@@@@QAEXXZ"
119
+ // CHECK: delete.notnull: ; preds = %arrayctor.cont
120
+ // CHECK-NEXT: %[[DEL_PTR:.*]] = getelementptr inbounds [1 x [3 x %struct.AllocatedAsArray]], ptr %[[THE_ARRAY:.*]], i32 0, i32 0
121
+ // X64-NEXT: %[[COOKIEGEP:.*]] = getelementptr inbounds i8, ptr %[[DEL_PTR]], i64 -8
122
+ // X86-NEXT: %[[COOKIEGEP:.*]] = getelementptr inbounds i8, ptr %[[DEL_PTR]], i32 -4
123
+ // X64-NEXT: %[[HOWMANY:.*]] = load i64, ptr %[[COOKIEGEP]]
124
+ // X86-NEXT: %[[HOWMANY:.*]] = load i32, ptr %[[COOKIEGEP]]
125
+ // X64-NEXT: %[[ISNOELEM:.*]] = icmp eq i64 %[[HOWMANY]], 0
126
+ // X86-NEXT: %[[ISNOELEM:.*]] = icmp eq i32 %[[HOWMANY]], 0
127
+ // CHECK-NEXT: br i1 %[[ISNOELEM]], label %vdtor.nocall, label %vdtor.call
128
+ // CHECK: vdtor.nocall: ; preds = %delete.notnull
129
+ // X64-NEXT: %[[HOWMANYBYTES:.*]] = mul i64 8, %[[HOWMANY]]
130
+ // X86-NEXT: %[[HOWMANYBYTES:.*]] = mul i32 4, %[[HOWMANY]]
131
+ // X64-NEXT: %[[ADDCOOKIESIZE:.*]] = add i64 %[[HOWMANYBYTES]], 8
132
+ // X86-NEXT: %[[ADDCOOKIESIZE:.*]] = add i32 %[[HOWMANYBYTES]], 4
133
+ // X64-NEXT: call void @"??_V@YAXPEAX_K@Z"(ptr noundef %[[COOKIEGEP]], i64 noundef %[[ADDCOOKIESIZE]])
134
+ // X86-NEXT: call void @"??_V@YAXPAXI@Z"(ptr noundef %[[COOKIEGEP]], i32 noundef %[[ADDCOOKIESIZE]])
135
+ // CHECK-NEXT: br label %delete.end
136
+ // CHECK: vdtor.call: ; preds = %delete.notnull
137
+ // CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[DEL_PTR]]
138
+ // CHECK-NEXT: %[[FPGEP:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE]], i64 0
139
+ // CHECK-NEXT: %[[FPLOAD:.*]] = load ptr, ptr %[[FPGEP]]
140
+ // X64-NEXT: %[[CALL:.*]] = call noundef ptr %[[FPLOAD]](ptr noundef nonnull align 8 dereferenceable(8) %[[DEL_PTR]], i32 noundef 3)
141
+ // X86-NEXT: %[[CALL:.*]] = call x86_thiscallcc noundef ptr %[[FPLOAD]](ptr noundef nonnull align 4 dereferenceable(4) %[[DEL_PTR]], i32 noundef 3)
142
+ // CHECK-NEXT: br label %delete.end
143
+ // CHECK: delete.end:
144
+ // CHECK-NEXT: ret void
145
+
102
146
// Vector dtor definition for Parrot.
103
147
// X64-LABEL: define weak dso_local noundef ptr @"??_EParrot@@UEAAPEAXI@Z"(
104
148
// X64-SAME: ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[IMPLICIT_PARAM:.*]]) unnamed_addr
@@ -169,3 +213,6 @@ void bar() {
169
213
// CHECK: dtor.call_delete:
170
214
// X64-NEXT: call void @"??3HasOperatorDelete@@SAXPEAX@Z"
171
215
// X86-NEXT: call void @"??3HasOperatorDelete@@SAXPAX@Z"
216
+
217
+ // X64: define weak dso_local noundef ptr @"??_EAllocatedAsArray@@UEAAPEAXI@Z"
218
+ // X86: define weak dso_local x86_thiscallcc noundef ptr @"??_EAllocatedAsArray@@UAEPAXI@Z"
0 commit comments