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