aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2005-01-07 10:01:00 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2005-01-07 10:01:00 +0100
commit8870e2121de6b86e33178bfc4646aa10bbe7069b (patch)
tree9ca4a80106abc12d7faa84a20a89676b90effb70 /gcc
parent4f1cfe85af8f53bdf31aa5b27cd6b5a7998f17bd (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--gcc/builtins.c86
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/20050105-2.c32
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);
+}