decl.c (grok_op_properties): Always use coerce_new_type and coerce_delete_type.
authorNathan Sidwell <nathan@codesourcery.com>
Wed, 8 Nov 2000 14:03:32 +0000 (14:03 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 8 Nov 2000 14:03:32 +0000 (14:03 +0000)
cp/ChangeLog
* decl.c (grok_op_properties): Always use coerce_new_type and
coerce_delete_type.
* decl2.c (coerce_new_type): Use c_size_type_node. Preserve
exception specification. Tidy up.
(coerce_delete_type): Preserve exception specification. Tidy up.
testsuite/ChangeLog
* g++.old-deja/g++.other/crash36.C: New test.

From-SVN: r37319

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.other/crash36.C [new file with mode: 0644]

index d11ff26..c11bad0 100644 (file)
@@ -1,3 +1,11 @@
+2000-11-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * decl.c (grok_op_properties): Always use coerce_new_type and
+       coerce_delete_type.
+       * decl2.c (coerce_new_type): Use c_size_type_node. Preserve
+       exception specification. Tidy up.
+       (coerce_delete_type): Preserve exception specification. Tidy up.
+
 2000-11-07  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
index 3356720..51591c1 100644 (file)
@@ -12447,27 +12447,14 @@ grok_op_properties (decl, virtualp, friendp)
       if (methodp)
        revert_static_member_fn (decl);
 
-      /* Take care of function decl if we had syntax errors.  */
-      if (argtypes == NULL_TREE)
-       TREE_TYPE (decl)
-         = build_function_type (ptr_type_node,
-                                hash_tree_chain (integer_type_node,
-                                                 void_list_node));
-      else
-       TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
+      TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
     }
   else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
     {
       if (methodp)
        revert_static_member_fn (decl);
 
-      if (argtypes == NULL_TREE)
-       TREE_TYPE (decl)
-         = build_function_type (void_type_node,
-                                hash_tree_chain (ptr_type_node,
-                                                 void_list_node));
-      else
-       TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
+      TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
     }
   else
     {
index 1af6d27..138adc1 100644 (file)
@@ -2301,23 +2301,34 @@ tree
 coerce_new_type (type)
      tree type;
 {
-  int e1 = 0, e2 = 0;
-
-  if (TREE_CODE (type) == METHOD_TYPE)
-    type = build_function_type (TREE_TYPE (type), TREE_CHAIN (TYPE_ARG_TYPES (type)));
-  if (! same_type_p (TREE_TYPE (type), ptr_type_node))
-    e1 = 1, error ("`operator new' must return type `void *'");
-
-  /* Technically the type must be `size_t', but we may not know
-     what that is.  */
-  if (TYPE_ARG_TYPES (type) == NULL_TREE)
-    e1 = 1, error ("`operator new' takes type `size_t' parameter");
-  else if (! same_type_p (TREE_VALUE (TYPE_ARG_TYPES (type)), sizetype))
-    e2 = 1, error ("`operator new' takes type `size_t' as first parameter");
-  if (e2)
-    type = build_function_type (ptr_type_node, tree_cons (NULL_TREE, sizetype, TREE_CHAIN (TYPE_ARG_TYPES (type))));
-  else if (e1)
-    type = build_function_type (ptr_type_node, TYPE_ARG_TYPES (type));
+  int e = 0;
+  tree args = TYPE_ARG_TYPES (type);
+
+  my_friendly_assert (TREE_CODE (type) == FUNCTION_TYPE, 20001107);
+  
+  if (!same_type_p (TREE_TYPE (type), ptr_type_node))
+    e = 1, cp_error ("`operator new' must return type `%T'", ptr_type_node);
+
+  if (!args || args == void_list_node
+      || !same_type_p (TREE_VALUE (args), c_size_type_node))
+    {
+      e = 2;
+      if (args && args != void_list_node)
+        args = TREE_CHAIN (args);
+      cp_error ("`operator new' takes type `size_t' (`%T') as first parameter", c_size_type_node);
+    }
+  switch (e)
+  {
+    case 2:
+      args = tree_cons (NULL_TREE, c_size_type_node, args);
+      /* FALLTHROUGH */
+    case 1:
+      type = build_exception_variant
+              (build_function_type (ptr_type_node, args),
+               TYPE_RAISES_EXCEPTIONS (type));
+      /* FALLTHROUGH */
+    default:;
+  }
   return type;
 }
 
@@ -2325,63 +2336,34 @@ tree
 coerce_delete_type (type)
      tree type;
 {
-  int e1 = 0, e2 = 0;
-#if 0
-  e3 = 0;
-#endif
-  tree arg_types = TYPE_ARG_TYPES (type);
-
-  if (TREE_CODE (type) == METHOD_TYPE)
-    {
-      type = build_function_type (TREE_TYPE (type), TREE_CHAIN (arg_types));
-      arg_types = TREE_CHAIN (arg_types);
-    }
-
-  if (TREE_TYPE (type) != void_type_node)
-    e1 = 1, error ("`operator delete' must return type `void'");
+  int e = 0;
+  tree args = TYPE_ARG_TYPES (type);
+  
+  my_friendly_assert (TREE_CODE (type) == FUNCTION_TYPE, 20001107);
 
-  if (arg_types == NULL_TREE
-      || ! same_type_p (TREE_VALUE (arg_types), ptr_type_node))
-    e2 = 1, error ("`operator delete' takes type `void *' as first parameter");
+  if (!same_type_p (TREE_TYPE (type), void_type_node))
+    e = 1, cp_error ("`operator delete' must return type `%T'", void_type_node);
 
-#if 0
-  if (arg_types
-      && TREE_CHAIN (arg_types)
-      && TREE_CHAIN (arg_types) != void_list_node)
+  if (!args || args == void_list_node
+      || !same_type_p (TREE_VALUE (args), ptr_type_node))
     {
-      /* Again, technically this argument must be `size_t', but again
-        we may not know what that is.  */
-      tree t2 = TREE_VALUE (TREE_CHAIN (arg_types));
-      if (! same_type_p (t2, sizetype))
-       e3 = 1, error ("second argument to `operator delete' must be of type `size_t'");
-      else if (TREE_CHAIN (TREE_CHAIN (arg_types)) != void_list_node)
-       {
-         e3 = 1;
-         if (TREE_CHAIN (TREE_CHAIN (arg_types)))
-           error ("too many arguments in declaration of `operator delete'");
-         else
-           error ("`...' invalid in specification of `operator delete'");
-       }
+      e = 2;
+      if (args && args != void_list_node)
+        args = TREE_CHAIN (args);
+      cp_error ("`operator delete' takes type `%T' as first parameter", ptr_type_node);
     }
-
-  if (e3)
-    arg_types = tree_cons (NULL_TREE, ptr_type_node,
-                          build_tree_list (NULL_TREE, sizetype));
-  else if (e3 |= e2)
-    {
-      if (arg_types == NULL_TREE)
-       arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
-      else
-       arg_types = tree_cons (NULL_TREE, ptr_type_node, TREE_CHAIN (arg_types));
-    }
-  else e3 |= e1;
-#endif
-
-  if (e2)
-    arg_types = tree_cons (NULL_TREE, ptr_type_node,
-                          arg_types ? TREE_CHAIN (arg_types): NULL_TREE);
-  if (e2 || e1)
-    type = build_function_type (void_type_node, arg_types);
+  switch (e)
+  {
+    case 2:
+      args = tree_cons (NULL_TREE, ptr_type_node, args);
+      /* FALLTHROUGH */
+    case 1:
+      type = build_exception_variant
+              (build_function_type (void_type_node, args),
+               TYPE_RAISES_EXCEPTIONS (type));
+      /* FALLTHROUGH */
+    default:;
+  }
 
   return type;
 }
index 304a3f0..d805774 100644 (file)
@@ -1,3 +1,7 @@
+2000-11-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.old-deja/g++.other/crash36.C: New test.
+
 2000-11-08  Jakub Jelinek  <jakub@redhat.com>
 
        * g++.old-deja/g++.other/init16.C: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash36.C b/gcc/testsuite/g++.old-deja/g++.other/crash36.C
new file mode 100644 (file)
index 0000000..11190cf
--- /dev/null
@@ -0,0 +1,21 @@
+// Build don't link:
+// Copyright (C) 2000 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 7 Nov 2000 <nathan@codesourcery.com>
+
+// Bug 573. We ICE'd verifying operator new and operator delete conformed
+// to the standard's expectation.
+
+void *operator new (__SIZE_TYPE__); // ok
+void operator new (__SIZE_TYPE__);  // ERROR - must return void *
+void *operator new ();              // ERROR - must take size_t
+void *operator new (char);          // ERROR - must take size_t
+void *operator new (__SIZE_TYPE__, ...) throw(); // ok
+
+void operator delete (void *) throw (); // ok
+int operator delete (void *) throw ();          // ERROR - must return void
+void operator delete () throw ();               // ERROR - must take void *
+void operator delete (int *) throw ();          // ERROR - must take void *
+void operator delete (void *, __SIZE_TYPE__) throw (); // ok
+
+void operator delete (...) throw ();             // ERROR - must take void *
+void operator delete (void *, ...) throw ();     // ok