On Mon, 14 Jan 2008, Joseph S. Myers wrote:

> On Mon, 14 Jan 2008, Richard Guenther wrote:
> 
> >  - document how integral promotion is performed on the implementation
> >    defined bitfields we allow as a GNU extension.  (4.9, "Integer
> >    promotion rules are extended for non-standard bit-field types to
> >    promote to the smallest integer type that can represent all values
> >    of the bit-field type.")
> 
> Once you define bit-fields to have their own types as explained in the C90 
> DRs and apparently intended in the C99 textual history, everything about 
> integer promotions follows from the standard (via the rules on integer 
> promotion rank which assign ranks to all those types).  If you don't 
> define that, other issues arise with no existing standard text to resolve 
> them, see <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1260.htm>.

Can you clarify on the resulting promotions?  As I remember the
standard defines promotions based on the representable values, so
long : 15 gets promoted to int, but long : 33 doesn't get promoted.
In the C++ FE at least we promote to the _declared_ type, that is,
to long in this case.  (Which I find more natural, but may be not
what the standard says).

Now, if you assign a rank to long : 15 (is it the same as int : 15?),
would it still promote to int or would it promote to long or neither?

The question arises when computing the value of say long : 33 i;
i << 16 >> 16.  Is the shift performed in long : 33 type?  Is an
out-of-range value truncated?

> Thus I think we should:
> 
> * Admit in the documentation that we really do have extended integer types 
> - one signed and one unsigned for each precision for which bit-fields are 
> allowed, other than those for which there are standard types.

Fine.

> * Say that bit-fields are assigned such types.

Does behavior change for bit-fields that are standard conforming or
only for implementation defined bit-fields of long.

> * Make the gimplifier (or a later tree-ssa pass) insert whatever 
> conversions / reductions in precision may be needed to produce trees 
> acceptable to expand, if you think expand can't handle the special types 
> reliably.  In particular, for arithmetic on such types and on all 
> conversions to such types.  (Without special types, special code is still 
> needed for assignments to bit-fields, no longer handled as conversions.)

(The problem is that I'm trying to exactly define what it should mean
to the middle-end to for example do a NOP conversion to a bitfield - this
is not at all clear)

Right.  C requests this via a langhook (which C++ doesn't use).  So for
C++ we for example miscompile

extern "C" void abort (void);

struct s
{
  unsigned long long f1 : 40;
  unsigned int f2 : 24;
} sv;

void __attribute__((noinline)) foo(unsigned int i)
{
  unsigned int tmp;
  sv.f2 = i;
  tmp = sv.f2;
  if (tmp != 0)
    abort ();
}

int main()
{
  foo (0xff000000u);
  return 0;
}

because expand expands

  i.0 = (<unnamed-unsigned:24>) i;

to nothing.

This inconsistent behavior of the middle-end is IMHO bad.

Richard.

Reply via email to