Author: modimo Date: 2021-06-23T17:15:12-07:00 New Revision: 42b99e094c4f57b52807c56641c0a545b4a9a600
URL: https://github.com/llvm/llvm-project/commit/42b99e094c4f57b52807c56641c0a545b4a9a600 DIFF: https://github.com/llvm/llvm-project/commit/42b99e094c4f57b52807c56641c0a545b4a9a600.diff LOG: [Clang] Check for returns_nonnull when deciding to add allocation null checks Non-throwing allocators currently will always get null-check code. However, if the non-throwing allocator is explicitly annotated with returns_nonnull the null check should be elided. Testing: ninja check-all added test case correctly elides Reviewed By: bruno Differential Revision: https://reviews.llvm.org/D102820 Added: Modified: clang/lib/AST/ExprCXX.cpp clang/test/CodeGenCXX/new.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index b5ccfe34cce1b..26844f412f366 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -275,7 +275,8 @@ CXXNewExpr *CXXNewExpr::CreateEmpty(const ASTContext &Ctx, bool IsArray, } bool CXXNewExpr::shouldNullCheckAllocation() const { - return getOperatorNew() + return !getOperatorNew()->hasAttr<ReturnsNonNullAttr>() && + getOperatorNew() ->getType() ->castAs<FunctionProtoType>() ->isNothrow() && diff --git a/clang/test/CodeGenCXX/new.cpp b/clang/test/CodeGenCXX/new.cpp index 2181534a6beb4..3142dba4bf683 100644 --- a/clang/test/CodeGenCXX/new.cpp +++ b/clang/test/CodeGenCXX/new.cpp @@ -176,6 +176,7 @@ void t13(int n) { struct Alloc{ int x; void* operator new[](size_t size); + __attribute__((returns_nonnull)) void *operator new[](size_t size, const std::nothrow_t &) throw(); void operator delete[](void* p); ~Alloc(); }; @@ -186,6 +187,10 @@ void f() { // CHECK: call void @_ZN5AllocD1Ev( // CHECK: call void @_ZN5AllocdaEPv(i8* delete[] new Alloc[10][20]; + // CHECK: [[P:%.*]] = call nonnull i8* @_ZN5AllocnaEmRKSt9nothrow_t(i64 808, {{.*}}) [[ATTR_NOUNWIND:#[^ ]*]] + // CHECK-NOT: icmp eq i8* [[P]], null + // CHECK: store i64 200 + delete[] new (nothrow) Alloc[10][20]; // CHECK: call noalias nonnull i8* @_Znwm // CHECK: call void @_ZdlPv(i8* delete new bool; @@ -328,7 +333,7 @@ namespace N3664 { // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_BUILTIN_DELETE]] delete[] p; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} - // CHECK: call noalias i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_BUILTIN_NOTHROW_NEW:#[^ ]*]] + // CHECK: call noalias i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE:#[^ ]*]] (void) new (nothrow) S[3]; // CHECK: call i8* @_Znwm15MyPlacementType(i64 4){{$}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits