[clang] 42b99e0 - [Clang] Check for returns_nonnull when deciding to add allocation null checks

via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 23 17:15:40 PDT 2021


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){{$}}


        


More information about the cfe-commits mailing list