mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-01 15:54:17 +08:00
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
This commit is contained in:
parent
321565d3fa
commit
36791f1ef1
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
120
gcc/cp/decl2.c
120
gcc/cp/decl2.c
@ -2301,23 +2301,34 @@ tree
|
||||
coerce_new_type (type)
|
||||
tree type;
|
||||
{
|
||||
int e1 = 0, e2 = 0;
|
||||
int e = 0;
|
||||
tree args = TYPE_ARG_TYPES (type);
|
||||
|
||||
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 *'");
|
||||
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);
|
||||
|
||||
/* 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));
|
||||
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);
|
||||
int e = 0;
|
||||
tree args = TYPE_ARG_TYPES (type);
|
||||
|
||||
my_friendly_assert (TREE_CODE (type) == FUNCTION_TYPE, 20001107);
|
||||
|
||||
if (TREE_CODE (type) == METHOD_TYPE)
|
||||
if (!same_type_p (TREE_TYPE (type), void_type_node))
|
||||
e = 1, cp_error ("`operator delete' must return type `%T'", void_type_node);
|
||||
|
||||
if (!args || args == void_list_node
|
||||
|| !same_type_p (TREE_VALUE (args), ptr_type_node))
|
||||
{
|
||||
type = build_function_type (TREE_TYPE (type), TREE_CHAIN (arg_types));
|
||||
arg_types = TREE_CHAIN (arg_types);
|
||||
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 (TREE_TYPE (type) != void_type_node)
|
||||
e1 = 1, error ("`operator delete' must return type `void'");
|
||||
|
||||
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 0
|
||||
if (arg_types
|
||||
&& TREE_CHAIN (arg_types)
|
||||
&& TREE_CHAIN (arg_types) != void_list_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'");
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
21
gcc/testsuite/g++.old-deja/g++.other/crash36.C
Normal file
21
gcc/testsuite/g++.old-deja/g++.other/crash36.C
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user