The attached patch avoids printing a diagnostic referencing the type
of an incompatible argument to the __atomic_xxx built-ins when the
argument is in error.  Doing otherwise causes an ICE as pointed out
in the bug, for both of which I am to blame.

Martin
gcc/testsuite/ChangeLog:
2016-01-20  Martin Sebor  <mse...@redhat.com>

	PR c/69405
	* gcc.dg/sync-fetch.c: New test.

gcc/c-family/ChangeLog:
2016-01-20  Martin Sebor  <mse...@redhat.com>

	PR c/69405
	* c-common.c (sync_resolve_size): Avoid printing diagnostic about
        an incompatible argument when the argument isn't a valid a tree
        node.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 1a2c21b..378afae 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -10704,8 +10704,11 @@ sync_resolve_size (tree function, vec<tree, va_gc> *params, bool fetch)
     return size;
 
  incompatible:
-  error ("operand type %qT is incompatible with argument %d of %qE",
-	 argtype, 1, function);
+  /* Issue the diagnostic only if the argument is valid, otherwise
+     it would be redundant at best and could be misleading.  */
+  if (argtype != error_mark_node)
+    error ("operand type %qT is incompatible with argument %d of %qE",
+	   argtype, 1, function);
   return 0;
 }
 
diff --git a/gcc/testsuite/gcc.dg/sync-fetch.c b/gcc/testsuite/gcc.dg/sync-fetch.c
new file mode 100644
index 0000000..44b6cdc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sync-fetch.c
@@ -0,0 +1,115 @@
+/* PR c/69405 - [6 Regression] ICE in c_tree_printer on an invalid
+   __atomic_fetch_add */
+/* Test to verify that the diagnostic doesn't cause an ICE when any
+   of the arguments to __atomic_fetch_OP is undeclared.  */
+/* { dg-do compile } */
+
+void test_add_undeclared_first_arg (void)
+{
+  int a = 0;
+  __atomic_fetch_add (&a, &b, 0);   /* { dg-error ".b. undeclared" } */
+}
+
+void test_sub_undeclared_first_arg (void)
+{
+  int a = 0;
+  __atomic_fetch_sub (&a, &b, 0);      /* { dg-error ".b. undeclared" } */
+}
+
+void test_or_undeclared_first_arg (void)
+{
+  int a = 0;
+  __atomic_fetch_or (&a, &b, 0);      /* { dg-error ".b. undeclared" } */
+}
+
+void test_and_undeclared_first_arg (void)
+{
+  int a = 0;
+  __atomic_fetch_and (&a, &b, 0);      /* { dg-error ".b. undeclared" } */
+}
+
+void test_xor_undeclared_first_arg (void)
+{
+  int a = 0;
+  __atomic_fetch_xor (&a, &b, 0);      /* { dg-error ".b. undeclared" } */
+}
+
+void test_nand_undeclared_first_arg (void)
+{
+  int a = 0;
+  __atomic_fetch_nand (&a, &b, 0);      /* { dg-error ".b. undeclared" } */
+}
+
+
+void test_add_undeclared_second_arg (void)
+{
+  int b = 0;
+  __atomic_fetch_add (&a, &b, 0);   /* { dg-error ".a. undeclared" } */
+}
+
+void test_sub_undeclared_second_arg (void)
+{
+  int b = 0;
+  __atomic_fetch_sub (&a, &b, 0);      /* { dg-error ".a. undeclared" } */
+}
+
+void test_or_undeclared_second_arg (void)
+{
+  int b = 0;
+  __atomic_fetch_or (&a, &b, 0);      /* { dg-error ".a. undeclared" } */
+}
+
+void test_and_undeclared_second_arg (void)
+{
+  int b = 0;
+  __atomic_fetch_and (&a, &b, 0);      /* { dg-error ".a. undeclared" } */
+}
+
+void test_xor_undeclared_second_arg (void)
+{
+  int b = 0;
+  __atomic_fetch_xor (&a, &b, 0);      /* { dg-error ".a. undeclared" } */
+}
+
+void test_nand_undeclared_second_arg (void)
+{
+  int b = 0;
+  __atomic_fetch_nand (&a, &b, 0);      /* { dg-error ".a. undeclared" } */
+}
+
+
+void test_add_undeclared_third_arg (void)
+{
+  int a = 0, b = 0;
+  __atomic_fetch_add (&a, &b, m);   /* { dg-error ".m. undeclared" } */
+}
+
+void test_sub_undeclared_third_arg (void)
+{
+  int a = 0, b = 0;
+  __atomic_fetch_sub (&a, &b, m);      /* { dg-error ".m. undeclared" } */
+}
+
+void test_or_undeclared_third_arg (void)
+{
+  int a = 0, b = 0;
+  __atomic_fetch_or (&a, &b, m);      /* { dg-error ".m. undeclared" } */
+}
+
+void test_and_undeclared_third_arg (void)
+{
+  int a = 0, b = 0;
+  __atomic_fetch_and (&a, &b, m);      /* { dg-error ".m. undeclared" } */
+}
+
+void test_xor_undeclared_third_arg (void)
+{
+  int a = 0, b = 0;
+  __atomic_fetch_xor (&a, &b, m);      /* { dg-error ".m. undeclared" } */
+}
+
+void test_nand_undeclared_third_arg (void)
+{
+  int a = 0, b = 0;
+  __atomic_fetch_nand (&a, &b, m);      /* { dg-error ".m. undeclared" } */
+}

Reply via email to