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:
parent
e488786134
commit
2efcfa4ef6
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user