Hello, As a followup to my previous message enquiring about the intent underlying various addressability checks in the gimplifier, attached is an example of patch which addresses the issues we're observing.
It for instance fixes an ICE in in expand_expr_addr_expr_1 on the testcase below: procedure P5 is type Long_Message is record Data : String (1 .. 16); end record; type Short_Message is record B : Boolean; Data : String (1 .. 4); end record; pragma Pack (Short_Message); procedure Process (LM : Long_Message; Size : Natural) is SM : Short_Message; begin SM.Data (1 .. Size) := LM.Data (1 .. Size); end; begin null; end; which is the one producing the tree excerpt quoted in the previous message (for SM.Data (1 .. Size) in Process). The patch bootstraps fine with languages="all,ada" on i686-pc-linux-gnu, and introduces no new regression. Regarding gimple predicates typically not recursing down trees (in accordance with the grammar), as I said << 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. >> So this patch is posted here primarily for discussion purposes. I'd welcome suggestions on better ways to address this, if the approach is indeed considered inappropriate. Thanks in advance for your help, With Kind Regards, Olivier
2006-06-19 Olivier Hainque <[EMAIL PROTECTED]> * tree-gimple.c (is_gimple_lvalue, is_gimple_addressable): Account for possibly nested bitfield component refs, not addressable while still valid lvalues. *** tree-gimple.c.ori Tue May 30 15:55:07 2006 --- tree-gimple.c Mon Jun 19 16:50:38 2006 *************** rhs_predicate_for (tree lhs) *** 139,149 **** 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); } /* Return true if T is a GIMPLE condition. */ --- 139,148 ---- bool is_gimple_lvalue (tree t) { ! return (TREE_CODE (t) == WITH_SIZE_EXPR ! || INDIRECT_REF_P (t) ! || handled_component_p (t) ! || is_gimple_variable (t)); } /* Return true if T is a GIMPLE condition. */ *************** is_gimple_condexpr (tree t) *** 159,166 **** bool is_gimple_addressable (tree t) { ! return (is_gimple_id (t) || handled_component_p (t) ! || INDIRECT_REF_P (t)); } /* Return true if T is function invariant. Or rather a restricted --- 158,181 ---- bool is_gimple_addressable (tree t) { ! if (is_gimple_id (t) || INDIRECT_REF_P (t)) ! return true; ! ! switch (TREE_CODE (t)) ! { ! case COMPONENT_REF: ! return ! !DECL_BIT_FIELD (TREE_OPERAND (t, 1)) ! && is_gimple_addressable (TREE_OPERAND (t, 0)); ! ! case VIEW_CONVERT_EXPR: ! case ARRAY_REF: case ARRAY_RANGE_REF: ! case REALPART_EXPR: case IMAGPART_EXPR: ! return is_gimple_addressable (TREE_OPERAND (t, 0)); ! ! default: ! return false; ! } } /* Return true if T is function invariant. Or rather a restricted *** gimplify.c.ori Tue May 30 15:54:59 2006 --- gimplify.c Mon Jun 19 16:55:00 2006 *************** gimplify_modify_expr (tree *expr_p, tree *** 3422,3430 **** return ret; /* 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); --- 3422,3431 ---- return ret; /* If we've got a variable sized assignment between two lvalues (i.e. does ! not involve a call), we can make things a bit more straightforward by ! converting the assignment to memcpy or memset as soon as both operands ! can have their address taken. */ ! if (TREE_CODE (*from_p) == WITH_SIZE_EXPR && is_gimple_addressable (*to_p)) { tree from = TREE_OPERAND (*from_p, 0); tree size = TREE_OPERAND (*from_p, 1);