This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Rant and proposal about bitfield semantics in our IL and the C/C++ Frontend
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.