summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-12-11 23:23:22 +0000
committerAnders Carlsson <andersca@mac.com>2009-12-11 23:23:22 +0000
commit12308f41e7e26e091950d868d0d2e00a2892fbf0 (patch)
tree9e3df94dbf50fafc9333181c3361b84c1a034b44 /clang/lib/Sema/SemaDeclCXX.cpp
parentf5303fe492116d077e6e1fabbde6f95ffa173010 (diff)
downloadbcm5719-llvm-12308f41e7e26e091950d868d0d2e00a2892fbf0.tar.gz
bcm5719-llvm-12308f41e7e26e091950d868d0d2e00a2892fbf0.zip
Improve diagnostics for malformed delete operator function declarations.
llvm-svn: 91180
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp59
1 files changed, 55 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5a7cba00e5f..32e391d8d03 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -4604,6 +4604,52 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
}
}
+static bool
+CheckOperatorDeleteDeclaration(Sema &SemaRef, const FunctionDecl *FnDecl) {
+ // C++ [basic.stc.dynamic.deallocation]p1:
+ // A program is ill-formed if deallocation functions are declared in a
+ // namespace scope other than global scope or declared static in global
+ // scope.
+ const DeclContext *DC = FnDecl->getDeclContext()->getLookupContext();
+ if (isa<NamespaceDecl>(DC)) {
+ return SemaRef.Diag(FnDecl->getLocation(),
+ diag::err_operator_new_delete_declared_in_namespace)
+ << FnDecl->getDeclName();
+ } else if (isa<TranslationUnitDecl>(DC) &&
+ FnDecl->getStorageClass() == FunctionDecl::Static) {
+ return SemaRef.Diag(FnDecl->getLocation(),
+ diag::err_operator_new_delete_declared_static)
+ << FnDecl->getDeclName();
+ }
+
+ // C++ [basic.stc.dynamic.deallocation]p2:
+ // Each deallocation function shall return void and its first parameter
+ // shall be void*.
+ QualType ResultType = FnDecl->getResultType();
+ if (!ResultType->isDependentType() && !ResultType->isVoidType()) {
+ return SemaRef.Diag(FnDecl->getLocation(),
+ diag::err_operator_new_delete_invalid_result_type)
+ << FnDecl->getDeclName() << SemaRef.Context.VoidTy;
+ }
+
+ 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) {
+ return SemaRef.Diag(FnDecl->getLocation(),
+ diag::err_operator_delete_param_type)
+ << FnDecl->getDeclName() << SemaRef.Context.VoidPtrTy;
+ }
+
+ return false;
+}
+
/// CheckOverloadedOperatorDeclaration - Check whether the declaration
/// of this overloaded operator is well-formed. If so, returns false;
/// otherwise, emits appropriate diagnostics and returns true.
@@ -4619,9 +4665,14 @@ bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) {
// described completely in 3.7.3. The attributes and restrictions
// found in the rest of this subclause do not apply to them unless
// explicitly stated in 3.7.3.
- // FIXME: Write a separate routine for checking this. For now, just allow it.
- if (Op == OO_Delete || Op == OO_Array_Delete)
+ if (Op == OO_Delete || Op == OO_Array_Delete) {
+ return CheckOperatorDeleteDeclaration(*this, FnDecl);
+ FnDecl->setInvalidDecl();
+ return true;
+ }
+
return false;
+ }
if (Op == OO_New || Op == OO_Array_New) {
bool ret = false;
@@ -4638,8 +4689,8 @@ bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) {
QualType ResultTy = Context.getCanonicalType(FnDecl->getResultType());
if (!ResultTy->isDependentType() && ResultTy != Context.VoidPtrTy)
return Diag(FnDecl->getLocation(),
- diag::err_operator_new_result_type) << FnDecl->getDeclName()
- << static_cast<QualType>(Context.VoidPtrTy);
+ diag::err_operator_new_delete_invalid_result_type)
+ << FnDecl->getDeclName() << Context.VoidPtrTy;
return ret;
}
OpenPOWER on IntegriCloud