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.