Hopefully one of the last P1s for GCC 6.  The problem in this PR was that we
were triggering an assert in build_va_arg on invalid code which used wrong type
of va_arg.  We should rather error out than ICE; this patch thus turns asserts
into errors.  Only removing the assert would probably work as well, because
gimplify.c checks the type of va_arg, but it seems to be better to give an
error earlier, in the FE.

The reason for dg-prune-output in the test is that e.g. with -m32 the test
compiles just fine without an error.  I suspect that's the case for other
arches, too.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2016-04-15  Marek Polacek  <pola...@redhat.com>

        PR c/70651
        * c-common.c (build_va_arg): Change two asserts into errors and return
        error_mark_node.

        * c-c++-common/pr70651.c: New test.

diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
index 30c815d..f2846bb 100644
--- gcc/c-family/c-common.c
+++ gcc/c-family/c-common.c
@@ -5725,7 +5725,12 @@ build_va_arg (location_t loc, tree expr, tree type)
       /* Verify that &ap is still recognized as having va_list type.  */
       tree canon_expr_type
        = targetm.canonical_va_list_type (TREE_TYPE (expr));
-      gcc_assert (canon_expr_type != NULL_TREE);
+      if (canon_expr_type == NULL_TREE)
+       {
+         error_at (loc,
+                   "first argument to %<va_arg%> not of type %<va_list%>");
+         return error_mark_node;
+       }
 
       return build_va_arg_1 (loc, type, expr);
     }
@@ -5793,7 +5798,12 @@ build_va_arg (location_t loc, tree expr, tree type)
       /* Verify that &ap is still recognized as having va_list type.  */
       tree canon_expr_type
        = targetm.canonical_va_list_type (TREE_TYPE (expr));
-      gcc_assert (canon_expr_type != NULL_TREE);
+      if (canon_expr_type == NULL_TREE)
+       {
+         error_at (loc,
+                   "first argument to %<va_arg%> not of type %<va_list%>");
+         return error_mark_node;
+       }
     }
   else
     {
diff --git gcc/testsuite/c-c++-common/pr70651.c 
gcc/testsuite/c-c++-common/pr70651.c
index e69de29..a91a2d8 100644
--- gcc/testsuite/c-c++-common/pr70651.c
+++ gcc/testsuite/c-c++-common/pr70651.c
@@ -0,0 +1,9 @@
+/* PR c/70651 */
+/* { dg-do compile } */
+/* { dg-prune-output "\[^\n\r\]*first argument to .va_arg. not of type 
.va_list.\[^\n\r\]*" } */
+
+void fn1 ()
+{
+  char **a = 0;
+  __builtin_va_arg (a, char **);
+}

        Marek

Reply via email to