aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorAndrew Pinski <pinskia@gcc.gnu.org>2004-12-04 06:11:45 -0800
committerAndrew Pinski <pinskia@gcc.gnu.org>2004-12-04 06:11:45 -0800
commit2efcfa4ef6cd96146871e8c7f4de5ed76a9fefab (patch)
treecbf7c78afc4e2cbb6aeed7f265db741b9c045876 /gcc/builtins.c
parente4887861341b842247647d2a5e2e45b45c358895 (diff)
downloadgcc-2efcfa4ef6cd96146871e8c7f4de5ed76a9fefab.zip
gcc-2efcfa4ef6cd96146871e8c7f4de5ed76a9fefab.tar.gz
gcc-2efcfa4ef6cd96146871e8c7f4de5ed76a9fefab.tar.bz2
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
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 6c17e23..7dbfb20 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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;
}