In fold_unary, CASE_CONVERT, the folding of the conversion into a bitwise AND
is performed only for INTEGER_TYPE, while it could very likely be performed
for BOOLEAN_TYPE and ENUMERAL_TYPE as well:

      /* Convert (T)(x & c) into (T)x & (T)c, if c is an integer
         constants (if x has signed type, the sign bit cannot be set
         in c).  This folds extension into the BIT_AND_EXPR.
         ??? We don't do it for BOOLEAN_TYPE or ENUMERAL_TYPE because they
         very likely don't have maximal range for their precision and this
         transformation effectively doesn't preserve non-maximal ranges.  */
      if (TREE_CODE (type) == INTEGER_TYPE
          && TREE_CODE (op0) == BIT_AND_EXPR
          && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)

The problem is that the transformation doesn't preserve non-maximal ranges for
a given precision and, as a consequence, VRP can draw different conclusions
on each side.

See gnat.dg/bit_packed_array3.adb.


-- 
           Summary: folding of conversion for BOOLEAN_TYPE or ENUMERAL_TYPE
           Product: gcc
           Version: 4.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ebotcazou at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36384

Reply via email to