From 46991d63642c5a29f62d8b92456f62b0fe564fd0 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 12 Dec 2009 00:16:02 +0000 Subject: [PATCH] More work on improving the operator delete diagnostics. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91187 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 10 ++++++++ lib/Sema/SemaDeclCXX.cpp | 28 +++++++++++++++------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 4e88a3eed3..0bd737e22b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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">; diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 5712555e7c..35846602ca 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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; }