]> granicus.if.org Git - clang/commitdiff
More work on improving the operator delete diagnostics.
authorAnders Carlsson <andersca@mac.com>
Sat, 12 Dec 2009 00:16:02 +0000 (00:16 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 12 Dec 2009 00:16:02 +0000 (00:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91187 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclCXX.cpp

index 4e88a3eed3561ae06733bc8621e66fdebb470c72..0bd737e22b323f597bc38bb83b89d3ca095226ec 100644 (file)
@@ -2239,10 +2239,20 @@ def err_operator_new_delete_declared_static : Error<
   "%0 cannot be declared static in global scope">;
 def err_operator_new_delete_invalid_result_type : Error<
   "%0 must return type %1">;
+def err_operator_new_delete_dependent_result_type : Error<
+  "%0 cannot have a dependent return type; use %1 instead">;
 def err_operator_new_delete_too_few_parameters : Error<
   "%0 must have at least one parameter.">;
+def err_operator_new_delete_template_too_few_parameters : Error<
+  "%0 template must have at least two parameters.">;
+
+def err_operator_new_dependent_param_type : Error<
+  "%0 cannot take a dependent type as first parameter; "
+  "use size_t (%1) instead">;
 def err_operator_new_param_type : Error<
   "%0 takes type size_t (%1) as first parameter">;
+def err_operator_delete_dependent_param_type : Error<
+  "%0 cannot take a dependent type as first parameter; use %1 instead">;
 def err_operator_delete_param_type : Error<
   "%0 takes type %1 as first parameter">;
 
index 5712555e7c4d4478d4118e210608d41f288c1854..35846602ca05879f1bf98c8d8d3bfad265a1fa3b 100644 (file)
@@ -4626,26 +4626,36 @@ CheckOperatorDeleteDeclaration(Sema &SemaRef, const FunctionDecl *FnDecl) {
   //   Each deallocation function shall return void and its first parameter 
   //   shall be void*.
   QualType ResultType = FnDecl->getResultType();
-  if (!ResultType->isDependentType() && !ResultType->isVoidType()) {
+  if (ResultType->isDependentType())
+    return SemaRef.Diag(FnDecl->getLocation(),
+                        diag::err_operator_new_delete_dependent_result_type)
+      << FnDecl->getDeclName() << SemaRef.Context.VoidTy;
+    
+  if (!ResultType->isVoidType())
     return SemaRef.Diag(FnDecl->getLocation(),
                         diag::err_operator_new_delete_invalid_result_type) 
       << FnDecl->getDeclName() << SemaRef.Context.VoidTy;
-  }
 
-  if (FnDecl->getNumParams() == 0) {
+  if (FnDecl->getDescribedFunctionTemplate() && FnDecl->getNumParams() < 2)
+    return SemaRef.Diag(FnDecl->getLocation(),
+                      diag::err_operator_new_delete_template_too_few_parameters)
+        << FnDecl->getDeclName();
+  else if (FnDecl->getNumParams() == 0)
     return SemaRef.Diag(FnDecl->getLocation(),
                         diag::err_operator_new_delete_too_few_parameters)
       << FnDecl->getDeclName();
-  }
 
-  QualType FirstParamType = 
-    SemaRef.Context.getCanonicalType(FnDecl->getParamDecl(0)->getType());
-  if (!FirstParamType->isDependentType() && 
-      FirstParamType != SemaRef.Context.VoidPtrTy) {
+  QualType FirstParamType = FnDecl->getParamDecl(0)->getType();
+  if (FirstParamType->isDependentType())
+    return SemaRef.Diag(FnDecl->getLocation(),
+                        diag::err_operator_delete_dependent_param_type)
+    << FnDecl->getDeclName() << SemaRef.Context.VoidPtrTy;
+
+  if (SemaRef.Context.getCanonicalType(FirstParamType) != 
+      SemaRef.Context.VoidPtrTy)
     return SemaRef.Diag(FnDecl->getLocation(),
                         diag::err_operator_delete_param_type)
       << FnDecl->getDeclName() << SemaRef.Context.VoidPtrTy;
-  }
   
   return false;
 }