Hi!

Here is an attempt to fix ICE on statement expression in "m" asm input
operand.  The problem is that gimplify_asm_expr attempts to mark it
addressable, but that can be just too late, a temporary the stmt-expression
gimplifies to might not be addressable and may be used already in the
gimplified code.  Normally the C/C++ FEs attempt to mark the operand
addressable already, but in case of statement expression the temporaries
might not exist yet.
The patch turns also the PR29119 testcase into invalid test, but you've
already said in that PR it should be invalid and I agree with that.

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

2016-01-19  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/67653
        * gimplify.c (gimplify_asm_expr): Error if it is too late to
        attempt to mark memory input operand addressable.

        * c-c++-common/pr67653.c: New test.
        * gcc.dg/torture/pr29119.c: Add dg-error.

--- gcc/gimplify.c.jj   2016-01-15 20:37:30.000000000 +0100
+++ gcc/gimplify.c      2016-01-18 16:05:21.125640974 +0100
@@ -5305,6 +5305,27 @@ gimplify_asm_expr (tree *expr_p, gimple_
            TREE_VALUE (link) = error_mark_node;
          tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
                                is_gimple_lvalue, fb_lvalue | fb_mayfail);
+         if (tret != GS_ERROR)
+           {
+             /* Unlike output operands, memory inputs are not guaranteed
+                to be lvalues by the FE, and while the expressions are
+                marked addressable there, if it is e.g. a statement
+                expression, temporaries in it might not end up being
+                addressable.  They might be already used in the IL and thus
+                it is too late to make them addressable now though.  */
+             tree x = TREE_VALUE (link);
+             while (handled_component_p (x))
+               x = TREE_OPERAND (x, 0);
+             if (TREE_CODE (x) == MEM_REF
+                 && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
+               x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
+             if ((TREE_CODE (x) == VAR_DECL
+                  || TREE_CODE (x) == PARM_DECL
+                  || TREE_CODE (x) == RESULT_DECL)
+                 && !TREE_ADDRESSABLE (x)
+                 && is_gimple_reg (x))
+               tret = GS_ERROR;
+           }
          mark_addressable (TREE_VALUE (link));
          if (tret == GS_ERROR)
            {
--- gcc/testsuite/c-c++-common/pr67653.c.jj     2016-01-18 16:03:49.302899912 
+0100
+++ gcc/testsuite/c-c++-common/pr67653.c        2016-01-18 16:03:20.000000000 
+0100
@@ -0,0 +1,8 @@
+/* PR middle-end/67653 */
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  __asm__ ("" : : "m" (({ static int a; a; })));       /* { dg-error "memory 
input 0 is not directly addressable" } */
+}
--- gcc/testsuite/gcc.dg/torture/pr29119.c.jj   2014-09-25 15:02:28.000000000 
+0200
+++ gcc/testsuite/gcc.dg/torture/pr29119.c      2016-01-18 22:33:32.090515087 
+0100
@@ -2,6 +2,6 @@
 
 void ldt_add_entry(void)
 {
-   __asm__ ("" :: "m"(({unsigned __v; __v;})));
+   __asm__ ("" :: "m"(({unsigned __v; __v;})));        /* { dg-error "memory 
input 0 is not directly addressable" } */
 }
 

        Jakub

Reply via email to