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

Reply via email to