modimo created this revision. modimo added reviewers: bruno, lebedev.ri, rsmith. Herald added subscribers: hoy, wenlei, lxfind. modimo requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
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 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D102820 Files: clang/lib/AST/ExprCXX.cpp clang/test/CodeGenCXX/new.cpp Index: clang/test/CodeGenCXX/new.cpp =================================================================== --- clang/test/CodeGenCXX/new.cpp +++ clang/test/CodeGenCXX/new.cpp @@ -176,6 +176,7 @@ 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 @@ // CHECK: call void @_ZN5AllocD1Ev( // CHECK: call void @_ZN5AllocdaEPv(i8* delete[] new Alloc[10][20]; + // CHECK: [[P:%.*]] = call nonnull i8* @_ZN5AllocnaEmRKSt9nothrow_t(i64 808, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE:#[^ ]*]] + // 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; Index: clang/lib/AST/ExprCXX.cpp =================================================================== --- clang/lib/AST/ExprCXX.cpp +++ clang/lib/AST/ExprCXX.cpp @@ -275,7 +275,8 @@ } bool CXXNewExpr::shouldNullCheckAllocation() const { - return getOperatorNew() + return !getOperatorNew()->hasAttr<ReturnsNonNullAttr>() && + getOperatorNew() ->getType() ->castAs<FunctionProtoType>() ->isNothrow() &&
Index: clang/test/CodeGenCXX/new.cpp =================================================================== --- clang/test/CodeGenCXX/new.cpp +++ clang/test/CodeGenCXX/new.cpp @@ -176,6 +176,7 @@ 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 @@ // CHECK: call void @_ZN5AllocD1Ev( // CHECK: call void @_ZN5AllocdaEPv(i8* delete[] new Alloc[10][20]; + // CHECK: [[P:%.*]] = call nonnull i8* @_ZN5AllocnaEmRKSt9nothrow_t(i64 808, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE:#[^ ]*]] + // 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; Index: clang/lib/AST/ExprCXX.cpp =================================================================== --- clang/lib/AST/ExprCXX.cpp +++ clang/lib/AST/ExprCXX.cpp @@ -275,7 +275,8 @@ } bool CXXNewExpr::shouldNullCheckAllocation() const { - return getOperatorNew() + return !getOperatorNew()->hasAttr<ReturnsNonNullAttr>() && + getOperatorNew() ->getType() ->castAs<FunctionProtoType>() ->isNothrow() &&
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits