From: Anders Carlsson Date: Sat, 12 Dec 2009 00:32:00 +0000 (+0000) Subject: Correctly diagnose [basic.stc.dynamic.allocation]p1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=20d45d2a9ebb8e20683b11287878a7e341bfea1a;p=clang Correctly diagnose [basic.stc.dynamic.allocation]p1 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91190 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index b00b1886f1..08fe28998d 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -4604,8 +4604,35 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType, } } +static inline bool +CheckOperatorNewDeleteDeclarationScope(Sema &SemaRef, + const FunctionDecl *FnDecl) { + const DeclContext *DC = FnDecl->getDeclContext()->getLookupContext(); + if (isa(DC)) { + return SemaRef.Diag(FnDecl->getLocation(), + diag::err_operator_new_delete_declared_in_namespace) + << FnDecl->getDeclName(); + } + + if (isa(DC) && + FnDecl->getStorageClass() == FunctionDecl::Static) { + return SemaRef.Diag(FnDecl->getLocation(), + diag::err_operator_new_delete_declared_static) + << FnDecl->getDeclName(); + } + + return true; +} + static bool CheckOperatorNewDeclaration(Sema &SemaRef, FunctionDecl *FnDecl) { + // C++ [basic.stc.dynamic.allocation]p1: + // A program is ill-formed if an allocation function is declared in a + // namespace scope other than global scope or declared static in global + // scope. + if (CheckOperatorNewDeleteDeclarationScope(SemaRef, FnDecl)) + return true; + bool ret = false; if (FunctionDecl::param_iterator Param = FnDecl->param_begin()) { QualType SizeTy = @@ -4632,17 +4659,8 @@ CheckOperatorDeleteDeclaration(Sema &SemaRef, const FunctionDecl *FnDecl) { // 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(DC)) { - return SemaRef.Diag(FnDecl->getLocation(), - diag::err_operator_new_delete_declared_in_namespace) - << FnDecl->getDeclName(); - } else if (isa(DC) && - FnDecl->getStorageClass() == FunctionDecl::Static) { - return SemaRef.Diag(FnDecl->getLocation(), - diag::err_operator_new_delete_declared_static) - << FnDecl->getDeclName(); - } + if (CheckOperatorNewDeleteDeclarationScope(SemaRef, FnDecl)) + return true; // C++ [basic.stc.dynamic.deallocation]p2: // Each deallocation function shall return void and its first parameter diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp new file mode 100644 index 0000000000..f8fd9f2dd5 --- /dev/null +++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -fsyntax-only -verify %s +#include + +struct A { + void *operator new(size_t); +}; + +namespace NS { + void *operator new(size_t);; // expected-error {{'operator new' cannot be declared inside a namespace}} +} + +static void *operator new(size_t); // expected-error {{'operator new' cannot be declared static in global scope}}