diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c897bdc6a0b..4b37be7ec65 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2004-07-12 Giovanni Bajo + + * decl.c (grok_op_properties): Reject [de-]allocation functions + declared in a namespace, or declared as static. + 2004-07-12 Nathan Sidwell * cp-tree.h (make_binfo): Remove. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f659b201dd3..4c6180caa32 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8508,6 +8508,25 @@ grok_op_properties (tree decl, int friendp, bool complain) } } + /* [basic.std.dynamic.allocation]/1: + + 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. + + The same also holds true for deallocation functions. */ + if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR + || operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR) + { + if (DECL_NAMESPACE_SCOPE_P (decl)) + { + if (CP_DECL_CONTEXT (decl) != global_namespace) + error ("`%D' may not be declared within a namespace", decl); + else if (!TREE_PUBLIC (decl)) + error ("`%D' may not be declared as static", decl); + } + } + if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR) TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl)); else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 08a38d89300..7abecb68e50 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-07-12 Giovanni Bajo + + * g++.dg/lookup/new2.C: New test. + * g++.old-deja/g++.ns/new1.C: Remove (ill-formed). + 2004-07-12 David Billinghurst (David.Billinghurst@riotinto.com) * gfortran.dg/g77/12002.f: Copy from g77.f-torture/compile . diff --git a/gcc/testsuite/g++.dg/lookup/new2.C b/gcc/testsuite/g++.dg/lookup/new2.C new file mode 100644 index 00000000000..ac161a5f339 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/new2.C @@ -0,0 +1,11 @@ +// { dg-do compile } +// Reject [de-]allocation functions declared in a namespace, or +// declared as static. + +namespace A { + void* operator new(unsigned s, int* p); // { dg-error "namespace" } + void operator delete(void*); // { dg-error "namespace" } +} + +static void* operator new(unsigned s, int* p); // { dg-error "static" } +static void operator delete(void*); // { dg-error "static" } diff --git a/gcc/testsuite/g++.old-deja/g++.ns/new1.C b/gcc/testsuite/g++.old-deja/g++.ns/new1.C deleted file mode 100644 index 27eb6d55da0..00000000000 --- a/gcc/testsuite/g++.old-deja/g++.ns/new1.C +++ /dev/null @@ -1,34 +0,0 @@ -// { dg-do run } -// Test whether N::operator new is different from ::operator new -#include -#include - -bool success; - -namespace N{ - void* operator new(size_t n){ - success = true; - return std::malloc(n); - } -} - -void *operator new(size_t n)throw(std::bad_alloc) -{ - static bool entered = false; - if(entered) - throw std::bad_alloc(); - entered = true; - void *result = N::operator new(n); - entered = false; - return result; -} - -int main() -{ - try{ - new int; - }catch(...){ - return 1; - } - return success?0:1; -}