diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1323,9 +1323,15 @@ /// /// We model such elidable calls with the 'builtin' attribute. llvm::Function *Fn = dyn_cast(CalleePtr); - if (CalleeDecl->isReplaceableGlobalAllocationFunction() && - Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) { - CallOrInvoke->addFnAttr(llvm::Attribute::Builtin); + if (CalleeDecl->isReplaceableGlobalAllocationFunction()) { + if (Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) { + CallOrInvoke->addFnAttr(llvm::Attribute::Builtin); + } + + if (CalleeDecl->getOverloadedOperator() == OO_Array_Delete || + CalleeDecl->getOverloadedOperator() == OO_Delete) { + CallOrInvoke->addParamAttr(0, llvm::Attribute::AllocatedPointer); + } } return RV; diff --git a/clang/test/CodeGen/pr53127.cpp b/clang/test/CodeGen/pr53127.cpp --- a/clang/test/CodeGen/pr53127.cpp +++ b/clang/test/CodeGen/pr53127.cpp @@ -69,7 +69,7 @@ // CHECK-NEXT: [[CALL24:%.*]] = call noundef zeroext i1 @_Z1ev() // CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[CALL24]] to i64 // CHECK-NEXT: [[TMP3:%.*]] = load ptr, ptr [[P_ADDR]], align 8 -// CHECK-NEXT: call void @_ZdlPv(ptr noundef [[TMP3]]) #[[ATTR8:[0-9]+]] +// CHECK-NEXT: call void @_ZdlPv(ptr allocptr noundef [[TMP3]]) #[[ATTR8:[0-9]+]] // CHECK-NEXT: ret void // void f(int* p, ...) diff --git a/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp b/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp --- a/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp +++ b/clang/test/CodeGenCXX/cxx1y-sized-deallocation.cpp @@ -50,59 +50,59 @@ D::D() {} // CHECK-LABEL: define weak_odr void @_Z3delIiEvv() -// CHECK: call void @_ZdlPvm(ptr noundef %{{[^ ]*}}, i64 noundef 4) -// CHECK: call void @_ZdaPv(ptr noundef %{{[^ ]*}}) +// CHECK: call void @_ZdlPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef 4) +// CHECK: call void @_ZdaPv(ptr allocptr noundef %{{[^ ]*}}) // -// CHECK: call void @_ZdlPvm(ptr noundef %{{[^ ]*}}, i64 noundef 4) -// CHECK: call void @_ZdaPv(ptr noundef %{{[^ ]*}}) +// CHECK: call void @_ZdlPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef 4) +// CHECK: call void @_ZdaPv(ptr allocptr noundef %{{[^ ]*}}) // CHECK-LABEL: declare void @_ZdlPvm(ptr // CHECK-LABEL: define weak_odr void @_Z3delI1BEvv() -// CHECK: call void @_ZdlPvm(ptr noundef %{{[^ ]*}}, i64 noundef 4) -// CHECK: call void @_ZdaPv(ptr noundef %{{[^ ]*}}) +// CHECK: call void @_ZdlPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef 4) +// CHECK: call void @_ZdaPv(ptr allocptr noundef %{{[^ ]*}}) // -// CHECK: call void @_ZdlPvm(ptr noundef %{{[^ ]*}}, i64 noundef 4) -// CHECK: call void @_ZdaPv(ptr noundef %{{[^ ]*}}) +// CHECK: call void @_ZdlPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef 4) +// CHECK: call void @_ZdaPv(ptr allocptr noundef %{{[^ ]*}}) // CHECK-LABEL: define weak_odr void @_Z3delI1CEvv() -// CHECK: call void @_ZdlPvm(ptr noundef %{{[^ ]*}}, i64 noundef 1) +// CHECK: call void @_ZdlPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef 1) // CHECK: mul i64 1, %{{[^ ]*}} // CHECK: add i64 %{{[^ ]*}}, 8 -// CHECK: call void @_ZdaPvm(ptr noundef %{{[^ ]*}}, i64 noundef %{{[^ ]*}}) +// CHECK: call void @_ZdaPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef %{{[^ ]*}}) // -// CHECK: call void @_ZdlPvm(ptr noundef %{{[^ ]*}}, i64 noundef 1) +// CHECK: call void @_ZdlPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef 1) // CHECK: mul i64 1, %{{[^ ]*}} // CHECK: add i64 %{{[^ ]*}}, 8 -// CHECK: call void @_ZdaPvm(ptr noundef %{{[^ ]*}}, i64 noundef %{{[^ ]*}}) +// CHECK: call void @_ZdaPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef %{{[^ ]*}}) // CHECK-LABEL: declare void @_ZdaPvm(ptr // CHECK-LABEL: define weak_odr void @_Z3delI1DEvv() -// CHECK: call void @_ZdlPvm(ptr noundef %{{[^ ]*}}, i64 noundef 8) +// CHECK: call void @_ZdlPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef 8) // CHECK: mul i64 8, %{{[^ ]*}} // CHECK: add i64 %{{[^ ]*}}, 8 -// CHECK: call void @_ZdaPvm(ptr noundef %{{[^ ]*}}, i64 noundef %{{[^ ]*}}) +// CHECK: call void @_ZdaPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef %{{[^ ]*}}) // // CHECK-NOT: Zdl // CHECK: call void %{{.*}} // CHECK-NOT: Zdl // CHECK: mul i64 8, %{{[^ ]*}} // CHECK: add i64 %{{[^ ]*}}, 8 -// CHECK: call void @_ZdaPvm(ptr noundef %{{[^ ]*}}, i64 noundef %{{[^ ]*}}) +// CHECK: call void @_ZdaPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef %{{[^ ]*}}) // CHECK-LABEL: define weak_odr void @_Z3delI1EEvv() -// CHECK: call void @_ZdlPvm(ptr noundef %{{[^ ]*}}, i64 noundef 1) -// CHECK: call void @_ZdaPv(ptr noundef %{{[^ ]*}}) +// CHECK: call void @_ZdlPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef 1) +// CHECK: call void @_ZdaPv(ptr allocptr noundef %{{[^ ]*}}) // // CHECK: call void @_ZN1EdlEPv(ptr noundef %{{[^ ]*}}) // CHECK: call void @_ZN1EdaEPv(ptr noundef %{{[^ ]*}}) // CHECK-LABEL: define weak_odr void @_Z3delI1FEvv() -// CHECK: call void @_ZdlPvm(ptr noundef %{{[^ ]*}}, i64 noundef 1) +// CHECK: call void @_ZdlPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef 1) // CHECK: mul i64 1, %{{[^ ]*}} // CHECK: add i64 %{{[^ ]*}}, 8 -// CHECK: call void @_ZdaPvm(ptr noundef %{{[^ ]*}}, i64 noundef %{{[^ ]*}}) +// CHECK: call void @_ZdaPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef %{{[^ ]*}}) // // CHECK: call void @_ZN1FdlEPvm(ptr noundef %{{[^ ]*}}, i64 noundef 1) // CHECK: mul i64 1, %{{[^ ]*}} @@ -111,4 +111,4 @@ // CHECK-LABEL: define linkonce_odr void @_ZN1DD0Ev(ptr {{[^,]*}} %this) -// CHECK: call void @_ZdlPvm(ptr noundef %{{[^ ]*}}, i64 noundef 8) +// CHECK: call void @_ZdlPvm(ptr allocptr noundef %{{[^ ]*}}, i64 noundef 8) diff --git a/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp b/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp --- a/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp +++ b/clang/test/CodeGenCXX/cxx1z-aligned-allocation.cpp @@ -28,11 +28,11 @@ // CHECK-LABEL: define {{.*}} @_Z2a0v() // CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @_ZnwmSt11align_val_t(i64 noundef 512, i64 noundef 32) -// CHECK: call void @_ZdlPvSt11align_val_t(ptr noundef %[[ALLOC]], i64 noundef 32) +// CHECK: call void @_ZdlPvSt11align_val_t(ptr allocptr noundef %[[ALLOC]], i64 noundef 32) // CHECK-MS-LABEL: define {{.*}} @"?a0@@YAPEAXXZ"() // CHECK-MS: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @"??2@YAPEAX_KW4align_val_t@std@@@Z"(i64 noundef 512, i64 noundef 32) // CHECK-MS: cleanuppad -// CHECK-MS: call void @"??3@YAXPEAXW4align_val_t@std@@@Z"(ptr noundef %[[ALLOC]], i64 noundef 32) +// CHECK-MS: call void @"??3@YAXPEAXW4align_val_t@std@@@Z"(ptr allocptr noundef %[[ALLOC]], i64 noundef 32) void *a0() { return new A; } // FIXME: Why don't we call the sized array deallocation overload in this case? @@ -43,22 +43,22 @@ // No array cookie. // CHECK-NOT: store // CHECK: invoke void @_ZN1AC1Ev( -// CHECK: call void @_ZdaPvSt11align_val_t(ptr noundef %[[ALLOC]], i64 noundef 32) +// CHECK: call void @_ZdaPvSt11align_val_t(ptr allocptr noundef %[[ALLOC]], i64 noundef 32) // CHECK-MS-LABEL: define {{.*}} @"?a1@@YAPEAXJ@Z"( // CHECK-MS: %[[ALLOC:.*]] = call noalias noundef nonnull align 32 ptr @"??_U@YAPEAX_KW4align_val_t@std@@@Z"(i64 noundef %{{.*}}, i64 noundef 32) // No array cookie. // CHECK-MS-NOT: store // CHECK-MS: invoke noundef ptr @"??0A@@QEAA@XZ"( // CHECK-MS: cleanuppad -// CHECK-MS: call void @"??_V@YAXPEAXW4align_val_t@std@@@Z"(ptr noundef %[[ALLOC]], i64 noundef 32) +// CHECK-MS: call void @"??_V@YAXPEAXW4align_val_t@std@@@Z"(ptr allocptr noundef %[[ALLOC]], i64 noundef 32) void *a1(long n) { return new A[n]; } // CHECK-LABEL: define {{.*}} @_Z2a2P1A( -// CHECK: call void @_ZdlPvmSt11align_val_t(ptr noundef %{{.*}}, i64 noundef 512, i64 noundef 32) #9 +// CHECK: call void @_ZdlPvmSt11align_val_t(ptr allocptr noundef %{{.*}}, i64 noundef 512, i64 noundef 32) #9 void a2(A *p) { delete p; } // CHECK-LABEL: define {{.*}} @_Z2a3P1A( -// CHECK: call void @_ZdaPvSt11align_val_t(ptr noundef %{{.*}}, i64 noundef 32) #9 +// CHECK: call void @_ZdaPvSt11align_val_t(ptr allocptr noundef %{{.*}}, i64 noundef 32) #9 void a3(A *p) { delete[] p; } @@ -170,7 +170,7 @@ #ifndef UNALIGNED // CHECK-LABEL: define {{.*}} @_Z2e0v( // CHECK: %[[ALLOC:.*]] = call noalias noundef nonnull align 4 ptr @_ZnwmSt11align_val_t(i64 noundef 512, i64 noundef 4) -// CHECK: call void @_ZdlPvSt11align_val_t(ptr noundef %[[ALLOC]], i64 noundef 4) +// CHECK: call void @_ZdlPvSt11align_val_t(ptr allocptr noundef %[[ALLOC]], i64 noundef 4) void *e0() { return new (std::align_val_t(4)) A; } // CHECK-LABEL: define {{.*}} @_Z2e1v( diff --git a/clang/test/CodeGenCXX/delete-two-arg.cpp b/clang/test/CodeGenCXX/delete-two-arg.cpp --- a/clang/test/CodeGenCXX/delete-two-arg.cpp +++ b/clang/test/CodeGenCXX/delete-two-arg.cpp @@ -43,7 +43,7 @@ // CHECK-NEXT: br i1 [[T1]], // CHECK: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i32 -4 // CHECK-NEXT: [[T5:%.*]] = load i32, ptr [[T3]] - // CHECK-NEXT: call void @_ZdaPv(ptr noundef [[T3]]) + // CHECK-NEXT: call void @_ZdaPv(ptr allocptr noundef [[T3]]) // CHECK-NEXT: br label ::delete[] p; } diff --git a/clang/test/CodeGenCXX/delete.cpp b/clang/test/CodeGenCXX/delete.cpp --- a/clang/test/CodeGenCXX/delete.cpp +++ b/clang/test/CodeGenCXX/delete.cpp @@ -93,7 +93,7 @@ // CHECK-NEXT: call void @_ZN5test11AD1Ev(ptr {{[^,]*}} [[CUR]]) // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq ptr [[CUR]], [[BEGIN]] // CHECK-NEXT: br i1 [[ISDONE]] - // CHECK: call void @_ZdaPv(ptr noundef [[ALLOC]]) + // CHECK: call void @_ZdaPv(ptr allocptr noundef [[ALLOC]]) } } @@ -137,7 +137,7 @@ // CHECK-NEXT: [[DTOR:%.*]] = load ptr, ptr [[T0]] // CHECK-NEXT: call void [[DTOR]](ptr {{[^,]*}} [[OBJ:%.*]]) // Call the global operator delete. - // CHECK-NEXT: call void @_ZdlPv(ptr noundef [[ALLOCATED]]) [[NUW:#[0-9]+]] + // CHECK-NEXT: call void @_ZdlPv(ptr allocptr noundef [[ALLOCATED]]) [[NUW:#[0-9]+]] ::delete xp; } } diff --git a/clang/test/CodeGenCXX/exceptions.cpp b/clang/test/CodeGenCXX/exceptions.cpp --- a/clang/test/CodeGenCXX/exceptions.cpp +++ b/clang/test/CodeGenCXX/exceptions.cpp @@ -36,7 +36,7 @@ // CHECK: [[NEW:%.*]] = call noalias nonnull ptr @_Znwm(i64 8) // CHECK-NEXT: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 5) // CHECK: ret ptr [[NEW]] - // CHECK: call void @_ZdlPv(ptr [[NEW]]) + // CHECK: call void @_ZdlPv(ptr allocptr [[NEW]]) return new A(5); } @@ -46,7 +46,7 @@ // CHECK-NEXT: [[FOO:%.*]] = invoke i32 @_ZN5test13fooEv() // CHECK: invoke void @_ZN5test11AC1Ei(ptr {{[^,]*}} [[NEW]], i32 [[FOO]]) // CHECK: ret ptr [[NEW]] - // CHECK: call void @_ZdlPv(ptr [[NEW]]) + // CHECK: call void @_ZdlPv(ptr allocptr [[NEW]]) extern int foo(); return new A(foo()); } @@ -71,7 +71,7 @@ // CHECK: ret ptr [[NEW]] // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]] // CHECK-NEXT: br i1 [[ISACTIVE]] - // CHECK: call void @_ZdlPv(ptr [[NEW]]) + // CHECK: call void @_ZdlPv(ptr allocptr [[NEW]]) return new A(B().x); } @@ -98,7 +98,7 @@ // CHECK: ret ptr [[NEW]] // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]] // CHECK-NEXT: br i1 [[ISACTIVE]] - // CHECK: call void @_ZdlPv(ptr [[NEW]]) + // CHECK: call void @_ZdlPv(ptr allocptr [[NEW]]) return new A(B()); } @@ -123,7 +123,7 @@ // CHECK: ret ptr [[NEW]] // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]] // CHECK-NEXT: br i1 [[ISACTIVE]] - // CHECK: call void @_ZdlPv(ptr [[NEW]]) + // CHECK: call void @_ZdlPv(ptr allocptr [[NEW]]) return new A(B(), B()); } A *f() { @@ -159,7 +159,7 @@ // CHECK: ret ptr [[RET]] // CHECK: [[ISACTIVE:%.*]] = load i1, ptr [[ACTIVE]] // CHECK-NEXT: br i1 [[ISACTIVE]] - // CHECK: call void @_ZdlPv(ptr [[NEW]]) + // CHECK: call void @_ZdlPv(ptr allocptr [[NEW]]) A *x; return (x = new A(makeB()), makeB(), x); } @@ -445,7 +445,7 @@ } // CHECK: define{{.*}} ptr @_ZN5test94testEv // CHECK: [[TEST9_NEW:%.*]] = call noalias nonnull ptr @_Znam - // CHECK: call void @_ZdaPv(ptr [[TEST9_NEW]]) + // CHECK: call void @_ZdaPv(ptr allocptr [[TEST9_NEW]]) } // In a destructor with a function-try-block, a return statement in a diff --git a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp --- a/clang/test/CodeGenCXX/microsoft-abi-structors.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-structors.cpp @@ -56,7 +56,7 @@ // DTORS-NEXT: br i1 %[[CONDITION]], label %[[CONTINUE_LABEL:[0-9a-z._]+]], label %[[CALL_DELETE_LABEL:[0-9a-z._]+]] // // DTORS: [[CALL_DELETE_LABEL]] -// DTORS-NEXT: call void @"??3@YAXPAX@Z"(ptr %[[THIS]]) +// DTORS-NEXT: call void @"??3@YAXPAX@Z"(ptr allocptr %[[THIS]]) // DTORS-NEXT: br label %[[CONTINUE_LABEL]] // // DTORS: [[CONTINUE_LABEL]] @@ -114,7 +114,7 @@ // CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds ptr, ptr %[[VTABLE]], i64 0 // CHECK-NEXT: %[[VDTOR:.*]] = load ptr, ptr %[[PVDTOR]] // CHECK-NEXT: %[[CALL:.*]] = call x86_thiscallcc ptr %[[VDTOR]](ptr {{[^,]*}} %[[OBJ_PTR_VALUE]], i32 0) -// CHECK-NEXT: call void @"??3@YAXPAX@Z"(ptr %[[CALL]]) +// CHECK-NEXT: call void @"??3@YAXPAX@Z"(ptr allocptr %[[CALL]]) // CHECK: ret void }