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