As reported in bug 100501 (plus duplicates), the gimplifier ICEs for C
tests involving a statement expression not returning a value as an asm
input.

The expected diagnostic for this case (as seen for C++ input) is one
coming from the gimplifier and so it seems reasonable to fix the
gimplifier to handle the GENERIC generated for this case by the C
front end, rather than trying to make the C front end detect it
earlier.  Thus, adjust two places in the gimplifier to work with
gimplifying a BIND_EXPR changing *expr_p to NULL_TREE.

Bootstrapped with no regressions for x86_64-pc-linux-gnu.  OK to commit?

        PR c/100501

gcc/
        * gimplify.cc (gimplify_expr): Do not call gimple_test_f on
        *expr_p when it has become null.
        (gimplify_asm_expr): Handle TREE_VALUE (link) becoming null.

gcc/testsuite/
        * gcc.dg/pr100501-1.c: New test.

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index fb0ca23bfb6c..090f8987d5d3 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -7457,6 +7457,13 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p)
            TREE_VALUE (link) = error_mark_node;
          tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
                                is_gimple_lvalue, fb_lvalue | fb_mayfail);
+         if (TREE_VALUE (link) == NULL_TREE)
+           {
+             /* This can occur when an asm input is a BIND_EXPR for a
+                statement expression not returning a value.  */
+             tret = GS_ERROR;
+             TREE_VALUE (link) = error_mark_node;
+           }
          if (tret != GS_ERROR)
            {
              /* Unlike output operands, memory inputs are not guaranteed
@@ -19662,10 +19669,11 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, 
gimple_seq *post_p,
 
   /* Otherwise we're gimplifying a subexpression, so the resulting
      value is interesting.  If it's a valid operand that matches
-     GIMPLE_TEST_F, we're done. Unless we are handling some
-     post-effects internally; if that's the case, we need to copy into
-     a temporary before adding the post-effects to POST_P.  */
-  if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
+     GIMPLE_TEST_F, or it's now NULL_TREE, we're done.  Unless we are
+     handling some post-effects internally; if that's the case, we need
+     to copy into a temporary before adding the post-effects to POST_P.  */
+  if (gimple_seq_empty_p (internal_post)
+      && (!*expr_p || (*gimple_test_f) (*expr_p)))
     goto out;
 
   /* Otherwise, we need to create a new temporary for the gimplified
diff --git a/gcc/testsuite/gcc.dg/pr100501-1.c 
b/gcc/testsuite/gcc.dg/pr100501-1.c
new file mode 100644
index 000000000000..b5b3781a9c2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr100501-1.c
@@ -0,0 +1,26 @@
+/* Test ICE for statement expression returning no value as asm input (bug
+   100501).  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int x;
+int g ();
+
+void
+f ()
+{
+  __asm__ ("" : : "m" (({}))); /* { dg-error "memory input 0 is not directly 
addressable" } */
+  __asm__ ("" : : "m" (({ ; }))); /* { dg-error "memory input 0 is not 
directly addressable" } */
+  __asm__ ("" : : "m" (({ (void) 0; }))); /* { dg-error "memory input 0 is not 
directly addressable" } */
+  __asm__ ("" : : "m" (({ f (); }))); /* { dg-error "memory input 0 is not 
directly addressable|using result of function returning 'void'" } */
+  __asm__ ("" : : "m" (({ f (); f (); }))); /* { dg-error "memory input 0 is 
not directly addressable" } */
+  __asm__ ("" : : "m" (({ x = g (); f (); }))); /* { dg-error "memory input 0 
is not directly addressable" } */
+  __asm__ ("" : : "m" (({ if (1) g (); }))); /* { dg-error "memory input 0 is 
not directly addressable" } */
+  __asm__ ("" : : "m" (({ if (1) g (); else g (); }))); /* { dg-error "memory 
input 0 is not directly addressable" } */
+  __asm__ ("" : : "m" (({ test : goto test; }))); /* { dg-error "memory input 
0 is not directly addressable" } */
+  __asm__ ("" : : "m" (({ return; }))); /* { dg-error "memory input 0 is not 
directly addressable" } */
+  __asm__ ("" : : "m" (({ while (1); }))); /* { dg-error "memory input 0 is 
not directly addressable" } */
+  __asm__ ("" : : "m" (({ do {} while (1); }))); /* { dg-error "memory input 0 
is not directly addressable" } */
+  __asm__ ("" : : "m" (({ for (;;); }))); /* { dg-error "memory input 0 is not 
directly addressable" } */
+  __asm__ ("" : : "m" (({ switch (x); }))); /* { dg-error "memory input 0 is 
not directly addressable" } */
+}

-- 
Joseph S. Myers
josmy...@redhat.com

Reply via email to