From 36791f1ef140da0a882b34f8969410574a4cd38e Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 8 Nov 2000 14:03:32 +0000 Subject: [PATCH] decl.c (grok_op_properties): Always use coerce_new_type and coerce_delete_type. 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 | 8 ++ gcc/cp/decl.c | 17 +--- gcc/cp/decl2.c | 122 +++++++++++-------------- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/g++.old-deja/g++.other/crash36.C | 21 +++++ 5 files changed, 87 insertions(+), 85 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.other/crash36.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d11ff26..c11bad0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2000-11-08 Nathan Sidwell + + * 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 * class.c (duplicate_tag_error, build_vtbl_initializer), decl.c diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 3356720..51591c1 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 1af6d27..138adc1 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 304a3f0..d805774 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2000-11-08 Nathan Sidwell + + * g++.old-deja/g++.other/crash36.C: New test. + 2000-11-08 Jakub Jelinek * 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 0000000..11190cf --- /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 + +// 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 -- 2.7.4