diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-01-07 10:01:00 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-01-07 10:01:00 +0100 |
commit | 8870e2121de6b86e33178bfc4646aa10bbe7069b (patch) | |
tree | 9ca4a80106abc12d7faa84a20a89676b90effb70 /gcc | |
parent | 4f1cfe85af8f53bdf31aa5b27cd6b5a7998f17bd (diff) | |
download | gcc-8870e2121de6b86e33178bfc4646aa10bbe7069b.zip gcc-8870e2121de6b86e33178bfc4646aa10bbe7069b.tar.gz gcc-8870e2121de6b86e33178bfc4646aa10bbe7069b.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/builtins.c | 86 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/20050105-2.c | 32 |
4 files changed, 83 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d9d38a6..47923a1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +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> * pa64-hpux.h (STARTFILE_SPEC): Fix typo in spec. diff --git a/gcc/builtins.c b/gcc/builtins.c index a6a80cf..b41212a 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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_3 (tree, rtx, rtx); 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_end (tree); static rtx expand_builtin_va_copy (tree); @@ -3743,43 +3743,13 @@ expand_builtin_args_info (tree arglist) return const0_rtx; } -/* Expand ARGLIST, from a call to __builtin_next_arg. */ +/* Expand a call to __builtin_next_arg. */ static rtx -expand_builtin_next_arg (tree arglist) +expand_builtin_next_arg (void) { - tree fntype = TREE_TYPE (current_function_decl); - - 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"); - + /* Checking arguments is already done in fold_builtin_next_arg + that must be called before this function. */ return expand_binop (Pmode, add_optab, current_function_internal_arg_pointer, current_function_arg_offset_rtx, @@ -3867,15 +3837,11 @@ expand_builtin_va_start (tree arglist) error ("too few arguments to function %<va_start%>"); return const0_rtx; } - if (TREE_CHAIN (chain)) - error ("too many arguments to function %<va_start%>"); 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); #ifdef EXPAND_BUILTIN_VA_START @@ -5256,7 +5222,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, case BUILT_IN_NEXT_ARG: if (fold_builtin_next_arg (arglist)) return const0_rtx; - return expand_builtin_next_arg (arglist); + return expand_builtin_next_arg (); case BUILT_IN_CLASSIFY_TYPE: return expand_builtin_classify_type (arglist); @@ -8671,11 +8637,29 @@ fold_builtin_next_arg (tree arglist) error ("%<va_start%> used in function with fixed args"); 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 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 is not quite the same as STRIP_NOPS. It does more. We must also strip off INDIRECT_EXPR for C++ reference @@ -8692,17 +8676,15 @@ fold_builtin_next_arg (tree arglist) 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"); - return true; + /* We want to verify the second parameter just once before the tree + optimizers are run and then avoid keeping it in the tree, + as otherwise we could warn even for correct code like: + void foo (int i, ...) + { va_list ap; i++; va_start (ap, i); va_end (ap); } */ + TREE_VALUE (arglist) = integer_zero_node; + TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node); } return false; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b4a0f09..e12f538 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +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> * gcc.dg/i386-local.c: Handle -m32/-m64 runs correctly. diff --git a/gcc/testsuite/gcc.dg/20050105-2.c b/gcc/testsuite/gcc.dg/20050105-2.c new file mode 100644 index 0000000..02ac159 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20050105-2.c @@ -0,0 +1,32 @@ +/* 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); +} |