aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel López-Ibáñez <manu@gcc.gnu.org>2008-08-21 19:05:46 +0000
committerManuel López-Ibáñez <manu@gcc.gnu.org>2008-08-21 19:05:46 +0000
commit2985f531b7834837d02a8d2745fdd8ec82b04acb (patch)
tree66df13a772649e0dbf3e19930affd1570d2d47fd
parent3d10ed6cbc7248d756077c1e7dc3533257c44a4f (diff)
downloadgcc-2985f531b7834837d02a8d2745fdd8ec82b04acb.zip
gcc-2985f531b7834837d02a8d2745fdd8ec82b04acb.tar.gz
gcc-2985f531b7834837d02a8d2745fdd8ec82b04acb.tar.bz2
re PR c/30457 (Please warn about va_start(ap, invalid))
2008-08-21 Manuel Lopez-Ibanez <manu@gcc.gnu.org> PR 30457 * builtins.c (fold_builtin_next_arg): Add warning about undefined behaviour. testsuite/ * gcc.dg/pr30457.c: New. From-SVN: r139406
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/builtins.c11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr30457.c26
4 files changed, 48 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 23783fd..55ffcb1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2008-08-21 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 30457
+ * builtins.c (fold_builtin_next_arg): Add warning about undefined
+ behaviour.
+
2008-08-21 Aldy Hernandez <aldyh@redhat.com>
* c-tree.h (grokfield): New argument.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 6695672..59e4119 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -11586,6 +11586,17 @@ fold_builtin_next_arg (tree exp, bool va_start_p)
it. */
warning (0, "second parameter of %<va_start%> not last named argument");
}
+
+ /* Undefined by C99 7.15.1.4p4 (va_start):
+ "If the parameter parmN is declared with the register storage
+ class, with a function or array type, or with a type that is
+ not compatible with the type that results after application of
+ the default argument promotions, the behavior is undefined."
+ */
+ else if (DECL_REGISTER (arg))
+ warning (0, "undefined behaviour when second parameter of "
+ "%<va_start%> is declared with %<register%> storage");
+
/* 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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0aa749e..d4015a9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-08-21 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 30457
+ * gcc.dg/pr30457.c: New.
+
2008-08-21 Aldy Hernandez <aldyh@redhat.com>
* gcc.dg/20011008-1.c: Test column.
diff --git a/gcc/testsuite/gcc.dg/pr30457.c b/gcc/testsuite/gcc.dg/pr30457.c
new file mode 100644
index 0000000..f52332d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr30457.c
@@ -0,0 +1,26 @@
+/* PR 30457 warn about va_start(ap, invalid) */
+/* { dg-do compile } */
+/* { dg-options "-std=c99" } */
+
+/* Undefined by C99 7.15.1.4p4 (va_start):
+ "If the parameter parmN is declared with the register storage
+ class, with a function or array type, or with a type that is
+ not compatible with the type that results after application of
+ the default argument promotions, the behavior is undefined." */
+
+#include <stdarg.h>
+
+void foo(register short paramN, ...)
+{
+ va_list ap;
+
+ va_start(ap, paramN); /* { dg-warning "undefined behaviour when second parameter of 'va_start' is declared with 'register' storage" } */
+
+ /* Undefined by C99 7.15.1.1p2: */
+ (void) va_arg(ap, char); /* { dg-warning "'char' is promoted to 'int' when passed through '...'" } */
+ /* { dg-message "note: .so you should pass .int. not .char. to .va_arg.." "" { target *-*-* } 20 } */
+ /* { dg-message "note: if this code is reached, the program will abort" "" { target *-*-* } 20 } */
+
+ va_end(ap);
+}
+