Hello, First a short description of a problem we are seeing, then a couple of related questions on addressability checks in the gimplifier.
>From a simple Ada testcase which I can provide if need be, the front-end is producing a MODIFY_EXPR with a lhs of the following shape when we get to gimplify_modify_expr: <array_range_ref type <array_type p5__process__T6b size <var_decl D.632 arg 0 <component_ref type <array_type p5__short_message__T4b arg 0 <var_decl sm type <record_type BLK size <integer_cst constant invariant 40> arg 1 <field_decl data type <array_type external packed bit-field nonaddressable SI align 1 offset_align 128 offset <integer_cst constant invariant 0> bit offset <integer_cst constant invariant 1> arg 1 <integer_cst 0x401d9048 constant invariant 1> in short, a variable size array_range_ref within a bitfield record component. The lhs remains of similar shape after gimplification, the rhs is of variable size as well, and we end up at this point in gimplify_modify_expr: /* If we've got a variable sized assignment between two lvalues (i.e. does not involve a call), then we can make things a bit more straightforward by converting the assignment to memcpy or memset. */ if (TREE_CODE (*from_p) == WITH_SIZE_EXPR) { tree from = TREE_OPERAND (*from_p, 0); tree size = TREE_OPERAND (*from_p, 1); if (TREE_CODE (from) == CONSTRUCTOR) return gimplify_modify_expr_to_memset (expr_p, size, want_value); if (is_gimple_addressable (from)) { *from_p = from; return gimplify_modify_expr_to_memcpy (expr_p, size, want_value); } } We get down into gimplify_modify_expr_to_memcpy, which builds ADDR_EXPRs for both operands, which ICEs later on from expand_expr_addr_expr_1 because the operand sketched above is not byte-aligned. The first puzzle to me is that there is no check made that the target is a valid argument for an ADDR_EXPR. AFAICS, it has been gimplified with is_gimple_lvalue/fb_lvalue as the predicate/fallback pair, but this currently doesn't imply the required properties. I first thought that a is_gimple_addressable (*to_p) addition to the outer condition would help, but it actually does not because the predicate is shallow and only checks a very restricted set of conditions (e.g. any ARRAY_RANGE_REF or COMPONENT_REF is considered "addressable"). This is actually the reason why the gimplified lhs tree is considered is_gimple_lvalue, from: bool is_gimple_lvalue (tree t) { return (is_gimple_addressable (t) || TREE_CODE (t) == WITH_SIZE_EXPR /* These are complex lvalues, but don't have addresses, so they go here. */ || TREE_CODE (t) == BIT_FIELD_REF); Assuming that the initial tree is valid GENERIC, it would seem that a more sophisticated addressability checker (recursing down some inner refs and checking DECL_BIT_FIELD on field decls in COMPONENT_REFs) might be required. I'm unclear whether this could/should be is_gimple_addressable, as comments from http://gcc.gnu.org/ml/gcc/2004-07/msg01255.html indicate that it not designed for this sort of operation. I'm pretty sure I'm missing implicit assumptions and/or bits of design intents in various places, so would appreciate input on the case and puzzles described above. Thanks very much in advance for your help, With Kind Regards, Olivier