Commit 77dbdb57 by Zack Weinberg

* c-decl.c (last_function_parms, last_function_parm_tags)

	(last_function_parm_others, current_function_parms)
	(current_function_parm_tags, current_function_parm_others):
	Delete.
	(ARG_INFO_PARMS, ARG_INFO_TAGS, ARG_INFO_TYPES, ARG_INFO_OTHERS):
	New macros.
	(grokdeclarator): For function definitions, save the arg-info
	block from the declarator in DECL_ARGUMENTS.
	(grokparms): Do not write to last_function_parm*.  Use ARG_INFO_*
	macros to operate on arg-info block.  Can assume ARG_INFO_PARMS
	contains only PARM_DECLs.  Improve diagnostics.
	(get_parm_info): Use ARG_INFO_* macros.  Improve comments and
	diagnostics.  Disable some expensive checks if not ENABLE_CHECKING.
	(store_parm_decls_newstyle): Take the function to operate on,
	and an arg-info block, as arguments; don't get anything from
	current_function_* globals.
	(store_parm_decls_oldstyle): Likewise.
	(store_parm_decls): Pass fndecl and its arg-info block down to
	store_parm_decls_newstyle/oldstyle.  Send functions with empty
	argument lists through store_parm_decls_newstyle to reduce
	overhead.
	(pushdecl): Comment on the problems with the call to copy_node.
	Clear DECL_ARGUMENTS of the old node after copying it, if it
	is an arg-info block instead of a chain of decls.
	(start_function): Do not manipulate current_function_parm* or
	last_function_parm*.

	* testsuite/gcc.dg/noncompile/incomplete-2.c: Move dg-error to
	proper line.

From-SVN: r79206
parent 305eeaeb
2004-03-09 Zack Weinberg <zack@codesourcery.com>
* c-decl.c (last_function_parms, last_function_parm_tags)
(last_function_parm_others, current_function_parms)
(current_function_parm_tags, current_function_parm_others):
Delete.
(ARG_INFO_PARMS, ARG_INFO_TAGS, ARG_INFO_TYPES, ARG_INFO_OTHERS):
New macros.
(grokdeclarator): For function definitions, save the arg-info
block from the declarator in DECL_ARGUMENTS.
(grokparms): Do not write to last_function_parm*. Use ARG_INFO_*
macros to operate on arg-info block. Can assume ARG_INFO_PARMS
contains only PARM_DECLs. Improve diagnostics.
(get_parm_info): Use ARG_INFO_* macros. Improve comments and
diagnostics. Disable some expensive checks if not ENABLE_CHECKING.
(store_parm_decls_newstyle): Take the function to operate on,
and an arg-info block, as arguments; don't get anything from
current_function_* globals.
(store_parm_decls_oldstyle): Likewise.
(store_parm_decls): Pass fndecl and its arg-info block down to
store_parm_decls_newstyle/oldstyle. Send functions with empty
argument lists through store_parm_decls_newstyle to reduce
overhead.
(pushdecl): Comment on the problems with the call to copy_node.
Clear DECL_ARGUMENTS of the old node after copying it, if it
is an arg-info block instead of a chain of decls.
(start_function): Do not manipulate current_function_parm* or
last_function_parm*.
2004-03-09 Roger Sayle <roger@eyesopen.com> 2004-03-09 Roger Sayle <roger@eyesopen.com>
Andrew Pinski <pinskia@physics.uc.edu> Andrew Pinski <pinskia@physics.uc.edu>
......
...@@ -83,37 +83,16 @@ static tree enum_next_value; ...@@ -83,37 +83,16 @@ static tree enum_next_value;
static int enum_overflow; static int enum_overflow;
/* Parsing a function declarator leaves a list of parameter names /* These #defines are for clarity in working with the information block
or a chain of parameter decls here. */ returned by get_parm_info. */
#define ARG_INFO_PARMS(args) TREE_PURPOSE(args)
#define ARG_INFO_TAGS(args) TREE_VALUE(args)
#define ARG_INFO_TYPES(args) TREE_CHAIN(args)
#define ARG_INFO_OTHERS(args) TREE_TYPE(args)
static tree last_function_parms; /* The file and line that the prototype came from if this is an
old-style definition; used for diagnostics in
/* ... and a chain of structure and enum types declared in the store_parm_decls_oldstyle. */
parmlist here. */
static tree last_function_parm_tags;
/* ... and a chain of all non-parameter declarations (such as
CONST_DECLs from enumerations) here. */
static tree last_function_parm_others;
/* After parsing the declarator that starts a function definition,
`start_function' puts the list of parameter names or chain of decls here
for `store_parm_decls' to find. */
static tree current_function_parms;
/* Similar, for last_function_parm_tags. */
static tree current_function_parm_tags;
/* And for last_function_parm_others. */
static tree current_function_parm_others;
/* Similar, for the file and line that the prototype came from if this is
an old-style definition. */
static location_t current_function_prototype_locus; static location_t current_function_prototype_locus;
...@@ -314,8 +293,6 @@ static tree lookup_name_current_level (tree); ...@@ -314,8 +293,6 @@ static tree lookup_name_current_level (tree);
static tree grokdeclarator (tree, tree, enum decl_context, int, tree *); static tree grokdeclarator (tree, tree, enum decl_context, int, tree *);
static tree grokparms (tree, int); static tree grokparms (tree, int);
static void layout_array_type (tree); static void layout_array_type (tree);
static void store_parm_decls_newstyle (void);
static void store_parm_decls_oldstyle (void);
static tree c_make_fname_decl (tree, int); static tree c_make_fname_decl (tree, int);
static void c_expand_body_1 (tree, int); static void c_expand_body_1 (tree, int);
static tree any_external_decl (tree); static tree any_external_decl (tree);
...@@ -1723,7 +1700,26 @@ pushdecl (tree x) ...@@ -1723,7 +1700,26 @@ pushdecl (tree x)
if (ext) if (ext)
{ {
if (duplicate_decls (x, ext)) if (duplicate_decls (x, ext))
{
/* XXX This copy_node call violates the basic
assumption that there is only one DECL for any
given object. This causes all sorts of problems
elsewhere. To correct it we must stop chaining
DECLs directly within the scope structure (work
in progress). -zw 2004-03-05 */
x = copy_node (ext); x = copy_node (ext);
/* Kludge around one of the worst consequences of
the above copy_node call, viz. that the arg_info
block created by get_parm_info can survive in a
copied FUNCTION_DECL after store_parm_decls is
done with it, and confuse the debug info
generators. */
if (TREE_CODE (ext) == FUNCTION_DECL
&& DECL_ARGUMENTS (ext)
&& TREE_CODE (DECL_ARGUMENTS (ext)) == TREE_LIST)
DECL_ARGUMENTS (ext) = 0;
}
} }
else else
record_external_decl (x); record_external_decl (x);
...@@ -3273,6 +3269,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -3273,6 +3269,7 @@ grokdeclarator (tree declarator, tree declspecs,
tree returned_attrs = NULL_TREE; tree returned_attrs = NULL_TREE;
bool bitfield = width != NULL; bool bitfield = width != NULL;
tree element_type; tree element_type;
tree arg_info = NULL_TREE;
if (decl_context == FUNCDEF) if (decl_context == FUNCDEF)
funcdef_flag = 1, decl_context = NORMAL; funcdef_flag = 1, decl_context = NORMAL;
...@@ -3970,10 +3967,14 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -3970,10 +3967,14 @@ grokdeclarator (tree declarator, tree declspecs,
} }
else if (TREE_CODE (declarator) == CALL_EXPR) else if (TREE_CODE (declarator) == CALL_EXPR)
{ {
/* Declaring a function type. Say it's a definition only
for the CALL_EXPR closest to the identifier. */
bool really_funcdef = (funcdef_flag
&& (TREE_CODE (TREE_OPERAND (declarator, 0))
== IDENTIFIER_NODE));
tree arg_types; tree arg_types;
/* Declaring a function type. /* Make sure we have a valid type for the function to return. */
Make sure we have a valid type for the function to return. */
if (type == error_mark_node) if (type == error_mark_node)
continue; continue;
...@@ -3994,13 +3995,9 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -3994,13 +3995,9 @@ grokdeclarator (tree declarator, tree declspecs,
/* Construct the function type and go to the next /* Construct the function type and go to the next
inner layer of declarator. */ inner layer of declarator. */
arg_info = TREE_OPERAND (declarator, 1);
arg_types = grokparms (arg_info, really_funcdef);
arg_types = grokparms (TREE_OPERAND (declarator, 1),
funcdef_flag
/* Say it's a definition
only for the CALL_EXPR
closest to the identifier. */
&& TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE);
/* Type qualifiers before the return type of the function /* Type qualifiers before the return type of the function
qualify the return type, not the function type. */ qualify the return type, not the function type. */
if (type_quals) if (type_quals)
...@@ -4036,7 +4033,7 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4036,7 +4033,7 @@ grokdeclarator (tree declarator, tree declspecs,
{ {
tree link; tree link;
for (link = last_function_parm_tags; for (link = ARG_INFO_TAGS (arg_info);
link; link;
link = TREE_CHAIN (link)) link = TREE_CHAIN (link))
TYPE_CONTEXT (TREE_VALUE (link)) = type; TYPE_CONTEXT (TREE_VALUE (link)) = type;
...@@ -4356,6 +4353,12 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4356,6 +4353,12 @@ grokdeclarator (tree declarator, tree declspecs,
TREE_PUBLIC (decl) TREE_PUBLIC (decl)
= !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO))); = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO)));
/* For a function definition, record the argument information
block in DECL_ARGUMENTS where store_parm_decls will look
for it. */
if (funcdef_flag)
DECL_ARGUMENTS (decl) = arg_info;
if (defaulted_int) if (defaulted_int)
C_FUNCTION_IMPLICIT_INT (decl) = 1; C_FUNCTION_IMPLICIT_INT (decl) = 1;
...@@ -4493,10 +4496,6 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4493,10 +4496,6 @@ grokdeclarator (tree declarator, tree declspecs,
of calls is different. The last call to `grokparms' is always the one of calls is different. The last call to `grokparms' is always the one
that contains the formal parameter names of a function definition. that contains the formal parameter names of a function definition.
Store in `last_function_parms' a chain of the decls of parms.
Also store in `last_function_parm_tags' a chain of the struct, union,
and enum tags declared among the parms.
Return a list of arg types to use in the FUNCTION_TYPE for this function. Return a list of arg types to use in the FUNCTION_TYPE for this function.
FUNCDEF_FLAG is nonzero for a function definition, 0 for FUNCDEF_FLAG is nonzero for a function definition, 0 for
...@@ -4504,74 +4503,80 @@ grokdeclarator (tree declarator, tree declspecs, ...@@ -4504,74 +4503,80 @@ grokdeclarator (tree declarator, tree declspecs,
when FUNCDEF_FLAG is zero. */ when FUNCDEF_FLAG is zero. */
static tree static tree
grokparms (tree parms_info, int funcdef_flag) grokparms (tree arg_info, int funcdef_flag)
{ {
tree first_parm = TREE_CHAIN (parms_info); tree arg_types = ARG_INFO_TYPES (arg_info);
last_function_parms = TREE_PURPOSE (parms_info);
last_function_parm_tags = TREE_VALUE (parms_info);
last_function_parm_others = TREE_TYPE (parms_info);
if (warn_strict_prototypes && first_parm == 0 && !funcdef_flag if (warn_strict_prototypes && arg_types == 0 && !funcdef_flag
&& !in_system_header) && !in_system_header)
warning ("function declaration isn't a prototype"); warning ("function declaration isn't a prototype");
if (first_parm != 0 if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE)
&& TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE)
{ {
if (! funcdef_flag) if (! funcdef_flag)
pedwarn ("parameter names (without types) in function declaration"); pedwarn ("parameter names (without types) in function declaration");
last_function_parms = first_parm; ARG_INFO_PARMS (arg_info) = ARG_INFO_TYPES (arg_info);
ARG_INFO_TYPES (arg_info) = 0;
return 0; return 0;
} }
else else
{ {
tree parm; tree parm, type, typelt;
tree typelt; unsigned int parmno;
/* If the arg types are incomplete in a declaration,
they must include undefined tags. /* If the arg types are incomplete in a declaration, they must
These tags can never be defined in the scope of the declaration, include undefined tags. These tags can never be defined in
so the types can never be completed, the scope of the declaration, so the types can never be
and no call can be compiled successfully. */ completed, and no call can be compiled successfully. */
for (parm = last_function_parms, typelt = first_parm; for (parm = ARG_INFO_PARMS (arg_info), typelt = arg_types, parmno = 1;
parm; parm;
parm = TREE_CHAIN (parm)) parm = TREE_CHAIN (parm), typelt = TREE_CHAIN (typelt), parmno++)
/* Skip over any enumeration constants declared here. */
if (TREE_CODE (parm) == PARM_DECL)
{ {
/* Barf if the parameter itself has an incomplete type. */ type = TREE_VALUE (typelt);
tree type = TREE_VALUE (typelt);
if (type == error_mark_node) if (type == error_mark_node)
continue; continue;
if (!COMPLETE_TYPE_P (type)) if (!COMPLETE_TYPE_P (type))
{ {
if (funcdef_flag && DECL_NAME (parm) != 0)
error ("parameter `%s' has incomplete type",
IDENTIFIER_POINTER (DECL_NAME (parm)));
else
warning ("parameter has incomplete type");
if (funcdef_flag) if (funcdef_flag)
{ {
if (DECL_NAME (parm))
error ("%Jparameter %u ('%D') has incomplete type",
parm, parmno, parm);
else
error ("%Jparameter %u has incomplete type",
parm, parmno);
TREE_VALUE (typelt) = error_mark_node; TREE_VALUE (typelt) = error_mark_node;
TREE_TYPE (parm) = error_mark_node; TREE_TYPE (parm) = error_mark_node;
} }
else
{
if (DECL_NAME (parm))
warning ("%Jparameter %u ('%D') has incomplete type",
parm, parmno, parm);
else
warning ("%Jparameter %u has incomplete type",
parm, parmno);
} }
typelt = TREE_CHAIN (typelt);
} }
}
return first_parm; return arg_types;
} }
} }
/* Return a tree_list node with info on a parameter list just parsed. /* Return a tree_list node with info on a parameter list just parsed.
The TREE_PURPOSE is a list of decls of those parms. This tree_list node should be examined using the ARG_INFO_* macros,
The TREE_VALUE is a list of structure, union and enum tags defined. defined above:
The TREE_CHAIN is a list of argument types to go in the FUNCTION_TYPE. ARG_INFO_PARMS: a list of parameter decls.
The TREE_TYPE is a list of non-parameter decls which appeared with the ARG_INFO_TAGS: a list of structure, union and enum tags defined.
parameters. ARG_INFO_TYPES: a list of argument types to go in the FUNCTION_TYPE.
This tree_list node is later fed to `grokparms'. ARG_INFO_OTHERS: a list of non-parameter decls (notably enumeration
constants) defined with the parameters.
This tree_list node is later fed to 'grokparms' and 'store_parm_decls'.
VOID_AT_END nonzero means append `void' to the end of the type-list. VOID_AT_END nonzero means append `void' to the end of the type-list.
Zero means the parmlist ended with an ellipsis so don't append `void'. */ Zero means the parmlist ended with an ellipsis so don't append `void'. */
...@@ -4588,10 +4593,10 @@ get_parm_info (int void_at_end) ...@@ -4588,10 +4593,10 @@ get_parm_info (int void_at_end)
static bool explained_incomplete_types = false; static bool explained_incomplete_types = false;
bool gave_void_only_once_err = false; bool gave_void_only_once_err = false;
/* Just "void" (and no ellipsis) is special. There are really no parms. /* Just 'void' (and no ellipsis) is special. There are really no parms.
But if the "void" is qualified (by "const" or "volatile"), or has a But if the 'void' is qualified (by 'const' or 'volatile'), or has a
storage class specifier ("register"), then the behavior is undefined; storage class specifier ('register'), then the behavior is undefined;
issue an error. Typedefs for "void" are OK (see DR#157). */ issue an error. Typedefs for 'void' are OK (see DR#157). */
if (void_at_end && parms != 0 if (void_at_end && parms != 0
&& TREE_CHAIN (parms) == 0 && TREE_CHAIN (parms) == 0
&& VOID_TYPE_P (TREE_TYPE (parms)) && VOID_TYPE_P (TREE_TYPE (parms))
...@@ -4600,18 +4605,22 @@ get_parm_info (int void_at_end) ...@@ -4600,18 +4605,22 @@ get_parm_info (int void_at_end)
if (TREE_THIS_VOLATILE (parms) if (TREE_THIS_VOLATILE (parms)
|| TREE_READONLY (parms) || TREE_READONLY (parms)
|| DECL_REGISTER (parms)) || DECL_REGISTER (parms))
error ("\"void\" as only parameter may not be qualified"); error ("'void' as only parameter may not be qualified");
return tree_cons (0, 0, tree_cons (0, void_type_node, 0)); list = make_node (TREE_LIST);
ARG_INFO_TYPES (list) = build_tree_list (0, void_type_node);
return list;
} }
/* Sanity check all of the parameter declarations. */ /* Sanity check all of the parameter declarations. */
for (decl = parms; decl; decl = TREE_CHAIN (decl)) for (decl = parms; decl; decl = TREE_CHAIN (decl))
{ {
#ifdef ENABLE_CHECKING
if (TREE_CODE (decl) != PARM_DECL) if (TREE_CODE (decl) != PARM_DECL)
abort (); abort ();
if (TREE_ASM_WRITTEN (decl)) if (TREE_ASM_WRITTEN (decl))
abort (); abort ();
#endif
/* Since there is a prototype, args are passed in their /* Since there is a prototype, args are passed in their
declared types. The back end may override this. */ declared types. The back end may override this. */
...@@ -4621,7 +4630,7 @@ get_parm_info (int void_at_end) ...@@ -4621,7 +4630,7 @@ get_parm_info (int void_at_end)
/* Check for (..., void, ...) and issue an error. */ /* Check for (..., void, ...) and issue an error. */
if (VOID_TYPE_P (type) && !DECL_NAME (decl) && !gave_void_only_once_err) if (VOID_TYPE_P (type) && !DECL_NAME (decl) && !gave_void_only_once_err)
{ {
error ("\"void\" must be the only parameter"); error ("'void' must be the only parameter");
gave_void_only_once_err = true; gave_void_only_once_err = true;
} }
...@@ -4638,7 +4647,7 @@ get_parm_info (int void_at_end) ...@@ -4638,7 +4647,7 @@ get_parm_info (int void_at_end)
if (!TREE_ASM_WRITTEN (decl)) if (!TREE_ASM_WRITTEN (decl))
abort (); abort ();
error ("%Jparameter \"%D\" has just a forward declaration", error ("%Jparameter '%D' has just a forward declaration",
decl, decl); decl, decl);
} }
...@@ -4665,9 +4674,9 @@ get_parm_info (int void_at_end) ...@@ -4665,9 +4674,9 @@ get_parm_info (int void_at_end)
} }
if (TREE_PURPOSE (decl)) if (TREE_PURPOSE (decl))
/* The first %s will be one of 'struct', 'union', or 'enum'. */ /* The %s will be one of 'struct', 'union', or 'enum'. */
warning ("\"%s %s\" declared inside parameter list", warning ("'%s %E' declared inside parameter list",
keyword, IDENTIFIER_POINTER (TREE_PURPOSE (decl))); keyword, TREE_PURPOSE (decl));
else else
/* The %s will be one of 'struct', 'union', or 'enum'. */ /* The %s will be one of 'struct', 'union', or 'enum'. */
warning ("anonymous %s declared inside parameter list", keyword); warning ("anonymous %s declared inside parameter list", keyword);
...@@ -4687,8 +4696,11 @@ get_parm_info (int void_at_end) ...@@ -4687,8 +4696,11 @@ get_parm_info (int void_at_end)
*last_type = type; *last_type = type;
} }
list = tree_cons (parms, tags, types); list = make_node (TREE_LIST);
TREE_TYPE (list) = others; ARG_INFO_PARMS (list) = parms;
ARG_INFO_TAGS (list) = tags;
ARG_INFO_TYPES (list) = types;
ARG_INFO_OTHERS (list) = others;
return list; return list;
} }
...@@ -5443,12 +5455,6 @@ start_function (tree declspecs, tree declarator, tree attributes) ...@@ -5443,12 +5455,6 @@ start_function (tree declspecs, tree declarator, tree attributes)
if (warn_about_return_type) if (warn_about_return_type)
pedwarn_c99 ("return type defaults to `int'"); pedwarn_c99 ("return type defaults to `int'");
/* Save the parm names or decls from this function's declarator
where store_parm_decls will find them. */
current_function_parms = last_function_parms;
current_function_parm_tags = last_function_parm_tags;
current_function_parm_others = last_function_parm_others;
/* Make the init_value nonzero so pushdecl knows this is not tentative. /* Make the init_value nonzero so pushdecl knows this is not tentative.
error_mark_node is replaced below (in poplevel) with the BLOCK. */ error_mark_node is replaced below (in poplevel) with the BLOCK. */
DECL_INITIAL (decl1) = error_mark_node; DECL_INITIAL (decl1) = error_mark_node;
...@@ -5624,13 +5630,13 @@ start_function (tree declspecs, tree declarator, tree attributes) ...@@ -5624,13 +5630,13 @@ start_function (tree declspecs, tree declarator, tree attributes)
need only record them as in effect and complain if any redundant need only record them as in effect and complain if any redundant
old-style parm decls were written. */ old-style parm decls were written. */
static void static void
store_parm_decls_newstyle (void) store_parm_decls_newstyle (tree fndecl, tree arg_info)
{ {
tree decl, last; tree decl, last;
tree fndecl = current_function_decl;
tree parms = current_function_parms; tree parms = ARG_INFO_PARMS (arg_info);
tree tags = current_function_parm_tags; tree tags = ARG_INFO_TAGS (arg_info);
tree others = current_function_parm_others; tree others = ARG_INFO_OTHERS (arg_info);
if (current_scope->parms || current_scope->names || current_scope->tags) if (current_scope->parms || current_scope->names || current_scope->tags)
{ {
...@@ -5701,13 +5707,12 @@ store_parm_decls_newstyle (void) ...@@ -5701,13 +5707,12 @@ store_parm_decls_newstyle (void)
definitions (separate parameter list and declarations). */ definitions (separate parameter list and declarations). */
static void static void
store_parm_decls_oldstyle (void) store_parm_decls_oldstyle (tree fndecl, tree arg_info)
{ {
tree parm, decl, last; tree parm, decl, last;
tree fndecl = current_function_decl;
/* This is the identifier list from the function declarator. */ /* This is the identifier list from the function declarator. */
tree parmids = current_function_parms; tree parmids = ARG_INFO_PARMS (arg_info);
/* We use DECL_WEAK as a flag to show which parameters have been /* We use DECL_WEAK as a flag to show which parameters have been
seen already, since it is not used on PARM_DECL. */ seen already, since it is not used on PARM_DECL. */
...@@ -5932,14 +5937,20 @@ store_parm_decls (void) ...@@ -5932,14 +5937,20 @@ store_parm_decls (void)
/* The function containing FNDECL, if any. */ /* The function containing FNDECL, if any. */
tree context = decl_function_context (fndecl); tree context = decl_function_context (fndecl);
/* True if this definition is written with a prototype. */ /* The argument information block for FNDECL. */
bool prototype = (current_function_parms tree arg_info = DECL_ARGUMENTS (fndecl);
&& TREE_CODE (current_function_parms) != TREE_LIST);
/* True if this definition is written with a prototype. Since this
is a function definition, we can treat a null parameter list
(i.e. "foo()") as prototyped (C99 6.7.5.3p14) - this reduces
overhead. */
bool prototype = (!ARG_INFO_PARMS (arg_info)
|| TREE_CODE (ARG_INFO_PARMS (arg_info)) != TREE_LIST);
if (prototype) if (prototype)
store_parm_decls_newstyle (); store_parm_decls_newstyle (fndecl, arg_info);
else else
store_parm_decls_oldstyle (); store_parm_decls_oldstyle (fndecl, arg_info);
/* The next call to pushlevel will be a function body. */ /* The next call to pushlevel will be a function body. */
......
2004-03-09 Zack Weinberg <zack@codesourcery.com>
* gcc.dg/noncompile/incomplete-2.c: Move dg-error to proper line.
2004-03-09 Roger Sayle <roger@eyesopen.com> 2004-03-09 Roger Sayle <roger@eyesopen.com>
* gcc.c-torture/execute/20040309-1.c: New test case. * gcc.c-torture/execute/20040309-1.c: New test case.
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
int g95_type_for_mode (enum machine_mode); int g95_type_for_mode (enum machine_mode);
int int
g95_type_for_mode (enum machine_mode mode) g95_type_for_mode (enum machine_mode mode) /* { dg-error "incomplete type" } */
{ /* { dg-error "has incomplete type" } */ {
return 0; return 0;
} }
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