summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2000-11-08 14:03:32 +0000
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2000-11-08 14:03:32 +0000
commitb7c82fb54a4b3a588f41ba2e8b2db88c8b68a455 (patch)
treee792402842697bf48e7211dc5dcc659ca42f56e4
parent49278702ccf462b71a7229405dfb6dbb6ffd060e (diff)
downloadgcc-b7c82fb54a4b3a588f41ba2e8b2db88c8b68a455.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@37319 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/decl.c17
-rw-r--r--gcc/cp/decl2.c122
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/crash36.C21
5 files changed, 87 insertions, 85 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d11ff26ff2d..c11bad0986d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 335672006cf..51591c18936 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
{
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 1af6d27b207..138adc12334 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 304a3f07332..d805774bd6a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..11190cf20dc
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/crash36.C
@@ -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