diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f2eb93636f0..06aae56d64e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-01-21 Jakub Jelinek + + PR middle-end/67653 + * gimplify.c (gimplify_asm_expr): Warn if it is too late to + attempt to mark memory input operand addressable and + call prepare_gimple_addressable in that case. Don't adjust + input_location for diagnostics, use error_at instead. + 2016-01-20 Peter Bergner * config/rs6000/ppc-auxv.h: New file. diff --git a/gcc/gimplify.c b/gcc/gimplify.c index c8de1e62abd..32bc1fdb2fb 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -5305,12 +5305,38 @@ 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 (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)) + { + warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), + input_location), 0, + "memory input %d is not directly addressable", + i); + prepare_gimple_addressable (&TREE_VALUE (link), pre_p); + } + } mark_addressable (TREE_VALUE (link)); if (tret == GS_ERROR) { - if (EXPR_HAS_LOCATION (TREE_VALUE (link))) - input_location = EXPR_LOCATION (TREE_VALUE (link)); - error ("memory input %d is not directly addressable", i); + error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location), + "memory input %d is not directly addressable", i); ret = tret; } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bd23b365483..0a2e22f0aa8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-01-21 Jakub Jelinek + + PR middle-end/67653 + * c-c++-common/pr67653.c: New test. + * gcc.dg/torture/pr29119.c: Add dg-warning. + 2016-01-20 Peter Bergner * gcc.target/powerpc/cpu-builtin-1.c: New test. diff --git a/gcc/testsuite/c-c++-common/pr67653.c b/gcc/testsuite/c-c++-common/pr67653.c new file mode 100644 index 00000000000..1b9f63ec626 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr67653.c @@ -0,0 +1,8 @@ +/* PR middle-end/67653 */ +/* { dg-do compile } */ + +void +foo (void) +{ + __asm__ ("" : : "m" (({ static int a; a; }))); /* { dg-warning "memory input 0 is not directly addressable" } */ +} diff --git a/gcc/testsuite/gcc.dg/torture/pr29119.c b/gcc/testsuite/gcc.dg/torture/pr29119.c index 63e5d8693a9..d4f02f12456 100644 --- a/gcc/testsuite/gcc.dg/torture/pr29119.c +++ b/gcc/testsuite/gcc.dg/torture/pr29119.c @@ -2,6 +2,5 @@ void ldt_add_entry(void) { - __asm__ ("" :: "m"(({unsigned __v; __v;}))); + __asm__ ("" :: "m"(({unsigned __v; __v;}))); /* { dg-warning "memory input 0 is not directly addressable" } */ } -