1*67e74705SXin Li // RUN: %clang_cc1 -triple i686-pc-linux-gnu %s -o - -emit-llvm -verify | FileCheck %s 2*67e74705SXin Li // expected-no-diagnostics 3*67e74705SXin Li 4*67e74705SXin Li typedef __typeof(sizeof(int)) size_t; 5*67e74705SXin Li 6*67e74705SXin Li namespace test1 { 7*67e74705SXin Li struct A { void operator delete(void*,size_t); int x; }; 8*67e74705SXin Li 9*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test11aEPNS_1AE( a(A * x)10*67e74705SXin Li void a(A *x) { 11*67e74705SXin Li // CHECK: load 12*67e74705SXin Li // CHECK-NEXT: icmp eq {{.*}}, null 13*67e74705SXin Li // CHECK-NEXT: br i1 14*67e74705SXin Li // CHECK: call void @_ZN5test11AdlEPvj(i8* %{{.*}}, i32 4) 15*67e74705SXin Li delete x; 16*67e74705SXin Li } 17*67e74705SXin Li } 18*67e74705SXin Li 19*67e74705SXin Li // Check that we make cookies for the two-arg delete even when using 20*67e74705SXin Li // the global allocator and deallocator. 21*67e74705SXin Li namespace test2 { 22*67e74705SXin Li struct A { 23*67e74705SXin Li int x; 24*67e74705SXin Li void *operator new[](size_t); 25*67e74705SXin Li void operator delete[](void *, size_t); 26*67e74705SXin Li }; 27*67e74705SXin Li 28*67e74705SXin Li // CHECK: define [[A:%.*]]* @_ZN5test24testEv() test()29*67e74705SXin Li A *test() { 30*67e74705SXin Li // CHECK: [[NEW:%.*]] = call i8* @_Znaj(i32 44) 31*67e74705SXin Li // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[NEW]] to i32* 32*67e74705SXin Li // CHECK-NEXT: store i32 10, i32* [[T0]] 33*67e74705SXin Li // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[NEW]], i32 4 34*67e74705SXin Li // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[A]]* 35*67e74705SXin Li // CHECK-NEXT: ret [[A]]* [[T2]] 36*67e74705SXin Li return ::new A[10]; 37*67e74705SXin Li } 38*67e74705SXin Li 39*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test24testEPNS_1AE( test(A * p)40*67e74705SXin Li void test(A *p) { 41*67e74705SXin Li // CHECK: [[P:%.*]] = alloca [[A]]*, align 4 42*67e74705SXin Li // CHECK-NEXT: store [[A]]* {{%.*}}, [[A]]** [[P]], align 4 43*67e74705SXin Li // CHECK-NEXT: [[T0:%.*]] = load [[A]]*, [[A]]** [[P]], align 4 44*67e74705SXin Li // CHECK-NEXT: [[T1:%.*]] = icmp eq [[A]]* [[T0]], null 45*67e74705SXin Li // CHECK-NEXT: br i1 [[T1]], 46*67e74705SXin Li // CHECK: [[T2:%.*]] = bitcast [[A]]* [[T0]] to i8* 47*67e74705SXin Li // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i32 -4 48*67e74705SXin Li // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i32* 49*67e74705SXin Li // CHECK-NEXT: [[T5:%.*]] = load i32, i32* [[T4]] 50*67e74705SXin Li // CHECK-NEXT: call void @_ZdaPv(i8* [[T3]]) 51*67e74705SXin Li // CHECK-NEXT: br label 52*67e74705SXin Li ::delete[] p; 53*67e74705SXin Li } 54*67e74705SXin Li } 55*67e74705SXin Li 56*67e74705SXin Li // rdar://problem/8913519 57*67e74705SXin Li namespace test3 { 58*67e74705SXin Li struct A { 59*67e74705SXin Li int x; 60*67e74705SXin Li void operator delete[](void *, size_t); 61*67e74705SXin Li }; 62*67e74705SXin Li struct B : A {}; 63*67e74705SXin Li 64*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test34testEv() test()65*67e74705SXin Li void test() { 66*67e74705SXin Li // CHECK: call i8* @_Znaj(i32 24) 67*67e74705SXin Li // CHECK-NEXT: bitcast 68*67e74705SXin Li // CHECK-NEXT: store i32 5 69*67e74705SXin Li (void) new B[5]; 70*67e74705SXin Li } 71*67e74705SXin Li } 72