While adding constant-folding for integral argument BIT_FIELD_REF I noticed we have no way of passing down BIT_FIELD_REF_UNSIGNED to fold_ternary. Luckily references to BIT_FIELD_REF_UNSIGNED are rare - only expansion cares for it, through the use of get_inner_reference.
So I propose to tighthen the type constraints we set on valid BIT_FIELD_REF to force its result type precision to match the extracted bit-field size. Which makes BIT_FIELD_REF_UNSIGNED redundant, as for integral type the signedness of the result will determine how it is extended to its full mode. For non-integral result types we always use unsigned extension and can force the bit-field size to match the mode precision here. So, minus fixing SRA and removing all traces of BIT_FIELD_REF_UNSIGNED, the following makes sense for me. Comments? Thanks, Richard. 2008-03-05 Richard Guenther <[EMAIL PROTECTED]> * tree.def (BIT_FIELD_REF): Constrain result type and its precision. * tree-cfg.c (verify_expr): Verify BIT_FIELD_REF constraints on result type and precision. * expr.c (get_inner_reference): Set unsignedp based on the result type of BIT_FIELD_REF. Index: tree.def =================================================================== *** tree.def (revision 132894) --- tree.def (working copy) *************** DEFTREECODE (COMPONENT_REF, "component_r *** 391,398 **** Operand 0 is the structure or union expression; operand 1 is a tree giving the constant number of bits being referenced; operand 2 is a tree giving the constant position of the first referenced bit. ! The field can be either a signed or unsigned field; ! BIT_FIELD_REF_UNSIGNED says which. */ DEFTREECODE (BIT_FIELD_REF, "bit_field_ref", tcc_reference, 3) /* The ordering of the following codes is optimized for the checking --- 391,399 ---- Operand 0 is the structure or union expression; operand 1 is a tree giving the constant number of bits being referenced; operand 2 is a tree giving the constant position of the first referenced bit. ! The result type width has to match the number of bits referenced. ! If the result type is integral, its signedness specifies how it is extended ! to its mode width. */ DEFTREECODE (BIT_FIELD_REF, "bit_field_ref", tcc_reference, 3) /* The ordering of the following codes is optimized for the checking Index: tree-cfg.c =================================================================== *** tree-cfg.c (revision 132894) --- tree-cfg.c (working copy) *************** verify_expr (tree *tp, int *walk_subtree *** 3273,3278 **** --- 3273,3294 ---- error ("invalid position or size operand to BIT_FIELD_REF"); return t; } + if (INTEGRAL_TYPE_P (TREE_TYPE (t)) + && (TYPE_PRECISION (TREE_TYPE (t)) + != TREE_INT_CST_LOW (TREE_OPERAND (t, 1)))) + { + error ("integral result type precision does not match " + "field size of BIT_FIELD_REF"); + return t; + } + if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) + && (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (t))) + != TREE_INT_CST_LOW (TREE_OPERAND (t, 1)))) + { + error ("mode precision of non-integral result does not " + "match field size of BIT_FIELD_REF"); + return t; + } } t = TREE_OPERAND (t, 0); Index: expr.c =================================================================== *** expr.c (revision 132893) --- expr.c (working copy) *************** get_inner_reference (tree exp, HOST_WIDE *** 5893,5899 **** else if (TREE_CODE (exp) == BIT_FIELD_REF) { size_tree = TREE_OPERAND (exp, 1); ! *punsignedp = BIT_FIELD_REF_UNSIGNED (exp); /* For vector types, with the correct size of access, use the mode of inner type. */ --- 5893,5900 ---- else if (TREE_CODE (exp) == BIT_FIELD_REF) { size_tree = TREE_OPERAND (exp, 1); ! *punsignedp = (! INTEGRAL_TYPE_P (TREE_TYPE (exp)) ! || TYPE_UNSIGNED (TREE_TYPE (exp))); /* For vector types, with the correct size of access, use the mode of inner type. */