re PR middle-end/17909 (ICE: verifiy_stms failed)

2004-12-04  Andrew  Pinski  <pinskia@physics.uc.edu>

        PR middle-end/17909
        * builtins.c (fold_builtin_next_arg): Export and return true
        when there is a warning or an error.
        (expand_builtin_va_start): When fold_builtin_next_arg returns true,
        return const0_rtx.
        (expand_builtin): Likewise.
        * gimplify.c (gimplify_call_expr): Error out if there is not
        enough arguments to va_start. Call fold_builtin_next_arg also
        on the second argument.
        * tree.h (fold_builtin_next_arg): Prototype.

From-SVN: r91727
This commit is contained in:
Andrew Pinski 2004-12-04 06:11:45 -08:00
parent e488786134
commit 2efcfa4ef6
3 changed files with 48 additions and 12 deletions

View File

@ -185,7 +185,6 @@ static tree fold_builtin_strcat (tree);
static tree fold_builtin_strncat (tree);
static tree fold_builtin_strspn (tree);
static tree fold_builtin_strcspn (tree);
static void fold_builtin_next_arg (tree);
static tree fold_builtin_sprintf (tree, int);
@ -3868,7 +3867,10 @@ expand_builtin_va_start (tree arglist)
if (TREE_CHAIN (chain))
error ("too many arguments to function %<va_start%>");
fold_builtin_next_arg (chain);
if (fold_builtin_next_arg (chain))
{
return const0_rtx;
}
nextarg = expand_builtin_next_arg (chain);
valist = stabilize_va_list (TREE_VALUE (arglist), 1);
@ -5249,7 +5251,8 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
/* Return the address of the first anonymous stack arg. */
case BUILT_IN_NEXT_ARG:
fold_builtin_next_arg (arglist);
if (fold_builtin_next_arg (arglist))
return const0_rtx;
return expand_builtin_next_arg (arglist);
case BUILT_IN_CLASSIFY_TYPE:
@ -8650,7 +8653,10 @@ fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
return build_function_call_expr (fn, arglist);
}
static void
/* Fold the new_arg's agruments (ARGLIST). Returns true if there was an error
produced. False otherwise. This is done so that we don't output the error
or warning twice or three times. */
bool
fold_builtin_next_arg (tree arglist)
{
tree fntype = TREE_TYPE (current_function_decl);
@ -8658,7 +8664,10 @@ fold_builtin_next_arg (tree arglist)
if (TYPE_ARG_TYPES (fntype) == 0
|| (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
== void_type_node))
error ("%<va_start%> used in function with fixed args");
{
error ("%<va_start%> used in function with fixed args");
return true;
}
else if (arglist)
{
tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
@ -8674,13 +8683,23 @@ fold_builtin_next_arg (tree arglist)
|| TREE_CODE (arg) == INDIRECT_REF)
arg = TREE_OPERAND (arg, 0);
if (arg != last_parm)
warning ("second parameter of %<va_start%> not last named argument");
{
/* FIXME: Sometimes with the tree optimizaters we can get the not the last argument
even though the user used the last argument. We just warn and set the arg to be
the last argument so that we will get wrong-code because of it. */
arg = last_parm;
warning ("second parameter of %<va_start%> not last named argument");
}
TREE_VALUE (arglist) = arg;
}
else
/* Evidently an out of date version of <stdarg.h>; can't validate
va_start's second argument, but can still work as intended. */
warning ("%<__builtin_next_arg%> called without an argument");
{
/* Evidently an out of date version of <stdarg.h>; can't validate
va_start's second argument, but can still work as intended. */
warning ("%<__builtin_next_arg%> called without an argument");
return true;
}
return false;
}

View File

@ -1744,9 +1744,25 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
}
if (DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_START)
/* Avoid gimplifying the second argument to va_start, which needs
to be the plain PARM_DECL. */
return gimplify_arg (&TREE_VALUE (TREE_OPERAND (*expr_p, 1)), pre_p);
{
tree arglist = TREE_OPERAND (*expr_p, 1);
if (!arglist || !TREE_CHAIN (arglist))
{
error ("too few arguments to function %<va_start%>");
*expr_p = build_empty_stmt ();
return GS_OK;
}
if (fold_builtin_next_arg (TREE_CHAIN (arglist)))
{
*expr_p = build_empty_stmt ();
return GS_OK;
}
/* Avoid gimplifying the second argument to va_start, which needs
to be the plain PARM_DECL. */
return gimplify_arg (&TREE_VALUE (TREE_OPERAND (*expr_p, 1)), pre_p);
}
}
/* There is a sequence point before the call, so any side effects in

View File

@ -3535,6 +3535,7 @@ extern tree fold_builtin (tree, bool);
extern tree fold_builtin_fputs (tree, bool, bool, tree);
extern tree fold_builtin_strcpy (tree, tree);
extern tree fold_builtin_strncpy (tree, tree);
extern bool fold_builtin_next_arg (tree);
extern enum built_in_function builtin_mathfn_code (tree);
extern tree build_function_call_expr (tree, tree);
extern tree mathfn_built_in (tree, enum built_in_function fn);