]> granicus.if.org Git - clang/commitdiff
PR17983: Fix crasher bug in C++1y mode when performing a non-global array
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 5 Dec 2013 08:30:59 +0000 (08:30 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 5 Dec 2013 08:30:59 +0000 (08:30 +0000)
delete on a class which has no array cookie and has no class-specific operator
new.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196488 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExprCXX.cpp
test/CodeGenCXX/cxx1y-sized-deallocation.cpp

index 162e46ecab1fadaab8e1bda9a1f500768e0cbf17..846aba897274f56af1c3a44f0b89c8371733e865 100644 (file)
@@ -6192,6 +6192,10 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
     Context.DeclarationNames.getCXXOperatorName(OO_Delete);
     if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
       return true;
+    // If there's no class-specific operator delete, look up the global
+    // non-array delete.
+    if (!OperatorDelete)
+      OperatorDelete = FindUsualDeallocationFunction(Loc, true, Name);
 
     MarkFunctionReferenced(Loc, OperatorDelete);
     
index 95a5cbb20ee57f29cb2047945c1010fd09cc5ff0..b2f740e80444e48c6a9a4fcff7c5001df6cd2b7a 100644 (file)
@@ -2233,8 +2233,7 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
     return true;
   }
 
-  // Look for a global declaration.
-  Operator = FindUsualDeallocationFunction(StartLoc, true, Name);
+  Operator = 0;
   return false;
 }
 
@@ -2384,7 +2383,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
 
         // Otherwise, the usual operator delete[] should be the
         // function we just found.
-        else if (isa<CXXMethodDecl>(OperatorDelete))
+        else if (OperatorDelete && isa<CXXMethodDecl>(OperatorDelete))
           UsualArrayDeleteWantsSize = (OperatorDelete->getNumParams() == 2);
       }
 
index 642e1e07f6cdf51d1b2509b3069b598d4eb9b9a4..7fd3ece3e02ce75b5d97980773296bf18d204ae5 100644 (file)
@@ -30,6 +30,8 @@ template<typename T>
 void del() {
   ::delete get<T*>();
   ::delete[] get<T*>();
+  delete get<T*>();
+  delete[] get<T*>();
 }
 
 template void del<A>();
@@ -44,6 +46,9 @@ D::D() {}
 // CHECK-LABEL: define weak_odr void @_Z3delIiEvv()
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+//
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
 
 // CHECK-LABEL: define linkonce void @_ZdlPvm(i8*
 // CHECK: call void @_ZdlPv(i8* %0)
@@ -51,12 +56,20 @@ D::D() {}
 // CHECK-LABEL: define weak_odr void @_Z3delI1BEvv()
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+//
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1CEvv()
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
 // CHECK: mul i64 1, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+//
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECK: mul i64 1, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
 
 // CHECK-LABEL: define linkonce void @_ZdaPvm(i8*
 // CHECK: call void @_ZdaPv(i8* %0)
@@ -66,25 +79,32 @@ D::D() {}
 // CHECK: mul i64 8, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+//
+// CHECK-NOT: Zdl
+// CHECK: call void %{{.*}}
+// CHECK-NOT: Zdl
+// CHECK: mul i64 8, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1EEvv()
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+//
+// CHECK: call void @_ZN1EdlEPv(i8* %{{[^ ]*}})
+// CHECK: call void @_ZN1EdaEPv(i8* %{{[^ ]*}})
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1FEvv()
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
 // CHECK: mul i64 1, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+//
+// CHECK: call void @_ZN1FdlEPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECK: mul i64 1, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZN1FdaEPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
 
-// CHECK-LABEL: define void @_Z10member_delv()
-// CHECK-NOT: Zdl
-// CHECK: call void %{{[^ ]*}}(%{{[^ ]*}}* %
-// CHECK-NOT: Zdl
-// CHECK: }
-void member_del() {
-  delete get<D*>();
-}
 
 // CHECK-LABEL: define linkonce_odr void @_ZN1DD0Ev(%{{[^ ]*}}* %this)
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 8)