decl.c (grok_op_properties): Reject [de-]allocation functions declared in a namespace...
authorGiovanni Bajo <giovannibajo@gcc.gnu.org>
Mon, 12 Jul 2004 17:54:49 +0000 (17:54 +0000)
committerGiovanni Bajo <giovannibajo@gcc.gnu.org>
Mon, 12 Jul 2004 17:54:49 +0000 (17:54 +0000)
* decl.c (grok_op_properties): Reject [de-]allocation functions
declared in a namespace, or declared as static.

* g++.dg/lookup/new2.C: New test.
* g++.old-deja/g++.ns/new1.C: Remove (ill-formed).

From-SVN: r84567

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/new2.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.ns/new1.C [deleted file]

index c897bdc..4b37be7 100644 (file)
@@ -1,3 +1,8 @@
+2004-07-12  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
+
+       * decl.c (grok_op_properties): Reject [de-]allocation functions
+       declared in a namespace, or declared as static.
+
 2004-07-12  Nathan Sidwell  <nathan@codesourcery.com>
 
        * cp-tree.h (make_binfo): Remove.
index f659b20..4c6180c 100644 (file)
@@ -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)
index 08a38d8..7abecb6 100644 (file)
@@ -1,3 +1,8 @@
+2004-07-12  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
+
+       * 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 (file)
index 0000000..ac161a5
--- /dev/null
@@ -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 (file)
index 27eb6d5..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// { dg-do run  }
-// Test whether N::operator new is different from ::operator new
-#include <new>
-#include <cstdlib>
-
-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;
-}