Commit 8870e212 by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/18828 (Extraneous warning with var_start and optimization)

	PR tree-optimization/18828
	* builtins.c (expand_builtin_next_arg): Remove argument and all
	the argument checking.
	(expand_builtin): Adjust caller.
	(expand_builtin_va_start): Likewise.  Remove error for too many
	arguments.
	(fold_builtin_next_arg): Issue error for too many arguments.
	After checking arguments, replace them with magic arguments that
	prevent further checking of the args.

	* gcc.dg/20050105-2.c: New test.

From-SVN: r93040
parent 4f1cfe85
2005-01-07 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/18828
* builtins.c (expand_builtin_next_arg): Remove argument and all
the argument checking.
(expand_builtin): Adjust caller.
(expand_builtin_va_start): Likewise. Remove error for too many
arguments.
(fold_builtin_next_arg): Issue error for too many arguments.
After checking arguments, replace them with magic arguments that
prevent further checking of the args.
2005-01-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 2005-01-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa64-hpux.h (STARTFILE_SPEC): Fix typo in spec. * pa64-hpux.h (STARTFILE_SPEC): Fix typo in spec.
......
...@@ -99,7 +99,7 @@ static rtx expand_builtin_mathfn (tree, rtx, rtx); ...@@ -99,7 +99,7 @@ static rtx expand_builtin_mathfn (tree, rtx, rtx);
static rtx expand_builtin_mathfn_2 (tree, rtx, rtx); static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
static rtx expand_builtin_mathfn_3 (tree, rtx, rtx); static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
static rtx expand_builtin_args_info (tree); static rtx expand_builtin_args_info (tree);
static rtx expand_builtin_next_arg (tree); static rtx expand_builtin_next_arg (void);
static rtx expand_builtin_va_start (tree); static rtx expand_builtin_va_start (tree);
static rtx expand_builtin_va_end (tree); static rtx expand_builtin_va_end (tree);
static rtx expand_builtin_va_copy (tree); static rtx expand_builtin_va_copy (tree);
...@@ -3743,43 +3743,13 @@ expand_builtin_args_info (tree arglist) ...@@ -3743,43 +3743,13 @@ expand_builtin_args_info (tree arglist)
return const0_rtx; return const0_rtx;
} }
/* Expand ARGLIST, from a call to __builtin_next_arg. */ /* Expand a call to __builtin_next_arg. */
static rtx static rtx
expand_builtin_next_arg (tree arglist) expand_builtin_next_arg (void)
{ {
tree fntype = TREE_TYPE (current_function_decl); /* Checking arguments is already done in fold_builtin_next_arg
that must be called before this function. */
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");
return const0_rtx;
}
if (arglist)
{
tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
tree arg = TREE_VALUE (arglist);
/* Strip off all nops for the sake of the comparison. This
is not quite the same as STRIP_NOPS. It does more.
We must also strip off INDIRECT_EXPR for C++ reference
parameters. */
while (TREE_CODE (arg) == NOP_EXPR
|| TREE_CODE (arg) == CONVERT_EXPR
|| TREE_CODE (arg) == NON_LVALUE_EXPR
|| TREE_CODE (arg) == INDIRECT_REF)
arg = TREE_OPERAND (arg, 0);
if (arg != last_parm)
warning ("second parameter of %<va_start%> not last named argument");
}
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");
return expand_binop (Pmode, add_optab, return expand_binop (Pmode, add_optab,
current_function_internal_arg_pointer, current_function_internal_arg_pointer,
current_function_arg_offset_rtx, current_function_arg_offset_rtx,
...@@ -3867,15 +3837,11 @@ expand_builtin_va_start (tree arglist) ...@@ -3867,15 +3837,11 @@ expand_builtin_va_start (tree arglist)
error ("too few arguments to function %<va_start%>"); error ("too few arguments to function %<va_start%>");
return const0_rtx; return const0_rtx;
} }
if (TREE_CHAIN (chain))
error ("too many arguments to function %<va_start%>");
if (fold_builtin_next_arg (chain)) if (fold_builtin_next_arg (chain))
{ return const0_rtx;
return const0_rtx;
}
nextarg = expand_builtin_next_arg (chain); nextarg = expand_builtin_next_arg ();
valist = stabilize_va_list (TREE_VALUE (arglist), 1); valist = stabilize_va_list (TREE_VALUE (arglist), 1);
#ifdef EXPAND_BUILTIN_VA_START #ifdef EXPAND_BUILTIN_VA_START
...@@ -5256,7 +5222,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, ...@@ -5256,7 +5222,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
case BUILT_IN_NEXT_ARG: case BUILT_IN_NEXT_ARG:
if (fold_builtin_next_arg (arglist)) if (fold_builtin_next_arg (arglist))
return const0_rtx; return const0_rtx;
return expand_builtin_next_arg (arglist); return expand_builtin_next_arg ();
case BUILT_IN_CLASSIFY_TYPE: case BUILT_IN_CLASSIFY_TYPE:
return expand_builtin_classify_type (arglist); return expand_builtin_classify_type (arglist);
...@@ -8671,11 +8637,29 @@ fold_builtin_next_arg (tree arglist) ...@@ -8671,11 +8637,29 @@ fold_builtin_next_arg (tree arglist)
error ("%<va_start%> used in function with fixed args"); error ("%<va_start%> used in function with fixed args");
return true; return true;
} }
else if (arglist) else if (!arglist)
{
/* 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;
}
/* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
when we checked the arguments and if needed issued a warning. */
else if (!TREE_CHAIN (arglist)
|| !integer_zerop (TREE_VALUE (arglist))
|| !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
|| TREE_CHAIN (TREE_CHAIN (arglist)))
{ {
tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl)); tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
tree arg = TREE_VALUE (arglist); tree arg = TREE_VALUE (arglist);
if (TREE_CHAIN (arglist))
{
error ("%<va_start%> used with too many arguments");
return true;
}
/* Strip off all nops for the sake of the comparison. This /* Strip off all nops for the sake of the comparison. This
is not quite the same as STRIP_NOPS. It does more. is not quite the same as STRIP_NOPS. It does more.
We must also strip off INDIRECT_EXPR for C++ reference We must also strip off INDIRECT_EXPR for C++ reference
...@@ -8692,17 +8676,15 @@ fold_builtin_next_arg (tree arglist) ...@@ -8692,17 +8676,15 @@ fold_builtin_next_arg (tree arglist)
argument. We just warn and set the arg to be the last argument. We just warn and set the arg to be the last
argument so that we will get wrong-code because of argument so that we will get wrong-code because of
it. */ it. */
arg = last_parm;
warning ("second parameter of %<va_start%> not last named argument"); warning ("second parameter of %<va_start%> not last named argument");
} }
TREE_VALUE (arglist) = arg; /* We want to verify the second parameter just once before the tree
} optimizers are run and then avoid keeping it in the tree,
else as otherwise we could warn even for correct code like:
{ void foo (int i, ...)
/* Evidently an out of date version of <stdarg.h>; can't validate { va_list ap; i++; va_start (ap, i); va_end (ap); } */
va_start's second argument, but can still work as intended. */ TREE_VALUE (arglist) = integer_zero_node;
warning ("%<__builtin_next_arg%> called without an argument"); TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
return true;
} }
return false; return false;
} }
......
2005-01-07 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/18828
* gcc.dg/20050105-2.c: New test.
2005-01-07 Andreas Jaeger <aj@suse.de> 2005-01-07 Andreas Jaeger <aj@suse.de>
* gcc.dg/i386-local.c: Handle -m32/-m64 runs correctly. * gcc.dg/i386-local.c: Handle -m32/-m64 runs correctly.
......
/* PR tree-optimization/18828 */
/* { dg-do compile } */
/* { dg-options "-O2" } */
#include <stdarg.h>
extern void abort (void);
void foo (int x, ...)
{
va_list ap;
if (x != 21)
abort ();
va_start (ap, x);
va_end (ap);
}
void bar (int x, ...)
{
va_list ap;
x++;
va_start (ap, x);
va_end (ap);
}
void baz (int x, ...)
{
va_list ap;
x = 0;
va_start (ap, x);
va_end (ap);
}
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