Commit bc298aa7 by Zack Weinberg Committed by Zack Weinberg

re PR c/13656 (ICE after redeclaring size_t in the system headers)

	PR 13656
	* c-decl.c (diagnose_mismatched_decls): Whenever newtype or
	oldtype is set, set *newtypep or *oldtypep too.  Do not set
	them at the very end.
	(validate_proto_after_old_defn): Restructure for comprehensibility;
	make error messages clearer.
testsuite:
	* gcc.dg/typedef-redecl.c: New test case.
	* gcc.dg/typedef-redecl.h: New support file.

From-SVN: r75787
parent 12a08b40
2004-01-12 Zack Weinberg <zack@codesourcery.com> 2004-01-12 Zack Weinberg <zack@codesourcery.com>
PR 13656
* c-decl.c (diagnose_mismatched_decls): Whenever newtype or
oldtype is set, set *newtypep or *oldtypep too. Do not set
them at the very end.
(validate_proto_after_old_defn): Restructure for comprehensibility;
make error messages clearer.
2004-01-12 Zack Weinberg <zack@codesourcery.com>
* varray.h (VARRAY_POP): Add checking variant, aborts on underflow. * varray.h (VARRAY_POP): Add checking variant, aborts on underflow.
(VARRAY_TOP): Use VARRAY_CHECK so the access is bounds-checked. (VARRAY_TOP): Use VARRAY_CHECK so the access is bounds-checked.
* varray.c: No need to prototype error. * varray.c: No need to prototype error.
......
...@@ -839,42 +839,59 @@ diagnose_arglist_conflict (tree newdecl, tree olddecl, ...@@ -839,42 +839,59 @@ diagnose_arglist_conflict (tree newdecl, tree olddecl,
static bool static bool
validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype) validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
{ {
tree type, parm; tree newargs, oldargs;
int nargs; int i;
/* Prototype decl follows defn w/o prototype. */
/* ??? Elsewhere TYPE_MAIN_VARIANT is not used in this context. */
for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype), #define END_OF_ARGLIST(t) (TYPE_MAIN_VARIANT (t) == void_type_node)
type = TYPE_ARG_TYPES (newtype),
nargs = 1; oldargs = TYPE_ACTUAL_ARG_TYPES (oldtype);
; newargs = TYPE_ARG_TYPES (newtype);
parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++) i = 1;
{
if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node for (;;)
&& TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node) {
tree oldargtype = TREE_VALUE (oldargs);
tree newargtype = TREE_VALUE (newargs);
if (END_OF_ARGLIST (oldargtype) && END_OF_ARGLIST (newargtype))
break;
/* Reaching the end of just one list means the two decls don't
agree on the number of arguments. */
if (END_OF_ARGLIST (oldargtype))
{ {
/* End of list. */ error ("%Jprototype for '%D' declares more arguments "
warning ("%Jprototype for '%D' follows non-prototype definition", "than previous old-style definition", newdecl, newdecl);
newdecl, newdecl); return false;
return true;
} }
else if (END_OF_ARGLIST (newargtype))
if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
|| TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
{ {
error ("%Jprototype for '%D' with different number of arguments " error ("%Jprototype for '%D' declares fewer arguments "
"follows non-prototype definition", newdecl, newdecl); "than previous old-style definition", newdecl, newdecl);
return false; return false;
} }
/* Type for passing arg must be consistent
with that declared for the arg. */ /* Type for passing arg must be consistent with that declared
if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type), for the arg. */
COMPARE_STRICT)) else if (! comptypes (oldargtype, newargtype, COMPARE_STRICT))
{ {
error ("%Jprototype for '%D' with incompatible argument %d " error ("%Jprototype for '%D' declares arg %d with incompatible type",
"follows non-prototype definition", newdecl, newdecl, nargs); newdecl, newdecl, i);
return false; return false;
} }
oldargs = TREE_CHAIN (oldargs);
newargs = TREE_CHAIN (newargs);
i++;
} }
/* If we get here, no errors were found, but do issue a warning
for this poor-style construct. */
warning ("%Jprototype for '%D' follows non-prototype definition",
newdecl, newdecl);
return true;
#undef END_OF_ARGLIST
} }
/* Subroutine of diagnose_mismatched_decls. Report the location of DECL, /* Subroutine of diagnose_mismatched_decls. Report the location of DECL,
...@@ -913,8 +930,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, ...@@ -913,8 +930,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
the previous decl - we're in an error cascade already. */ the previous decl - we're in an error cascade already. */
if (olddecl == error_mark_node || newdecl == error_mark_node) if (olddecl == error_mark_node || newdecl == error_mark_node)
return false; return false;
oldtype = TREE_TYPE (olddecl); *oldtypep = oldtype = TREE_TYPE (olddecl);
newtype = TREE_TYPE (newdecl); *newtypep = newtype = TREE_TYPE (newdecl);
if (oldtype == error_mark_node || newtype == error_mark_node) if (oldtype == error_mark_node || newtype == error_mark_node)
return false; return false;
...@@ -946,7 +963,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, ...@@ -946,7 +963,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
tree trytype = match_builtin_function_types (newtype, oldtype); tree trytype = match_builtin_function_types (newtype, oldtype);
if (trytype && comptypes (newtype, trytype, COMPARE_STRICT)) if (trytype && comptypes (newtype, trytype, COMPARE_STRICT))
oldtype = trytype; *oldtypep = oldtype = trytype;
else else
{ {
/* If types don't match for a built-in, throw away the /* If types don't match for a built-in, throw away the
...@@ -978,7 +995,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, ...@@ -978,7 +995,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
{ {
pedwarn ("%Jconflicting types for '%D'", newdecl, newdecl); pedwarn ("%Jconflicting types for '%D'", newdecl, newdecl);
/* Make sure we keep void as the return type. */ /* Make sure we keep void as the return type. */
TREE_TYPE (newdecl) = newtype = oldtype; TREE_TYPE (newdecl) = *newtypep = newtype = oldtype;
C_FUNCTION_IMPLICIT_INT (newdecl) = 0; C_FUNCTION_IMPLICIT_INT (newdecl) = 0;
pedwarned = true; pedwarned = true;
} }
...@@ -1230,8 +1247,6 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, ...@@ -1230,8 +1247,6 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
if (warned || pedwarned) if (warned || pedwarned)
locate_old_decl (olddecl, pedwarned ? pedwarn : warning); locate_old_decl (olddecl, pedwarned ? pedwarn : warning);
*newtypep = newtype;
*oldtypep = oldtype;
return true; return true;
} }
......
2004-01-12 Zack Weinberg <zack@codesourcery.com>
PR 13656
* gcc.dg/typedef-redecl.c: New test case.
* gcc.dg/typedef-redecl.h: New support file.
2004-01-13 Jan Hubicka <jh@suse.cz> 2004-01-13 Jan Hubicka <jh@suse.cz>
* gcc.dg/always_inline.c: New test. * gcc.dg/always_inline.c: New test.
......
/* Redeclaration of typedef (invalid but accepted in system headers)
causes ICE; PR 13656. Test case by Richard Sandiford <rsandifo@redhat.com>,
reduced from glibc. */
#include "typedef-redecl.h"
x a;
/* Redeclaration of typedef (invalid but accepted in system headers)
causes ICE; PR 13656. Test case by Richard Sandiford <rsandifo@redhat.com>,
reduced from glibc. */
#pragma GCC system_header
typedef int x;
typedef int x;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment