Aside of corner cases associated with signedness, there's another fun pile we are handling strangely. Namely, treatment of integer promotions and conversions. What standard says: * there's a well-defined behaviour for bitfields based on _Bool, signed int and unsigned int (int-based is equivalent to one signed or unsigned). We get it right, AFAICS, and so does gcc. * implementation can do bitfields based on other types. Fair enough. Both sparse and gcc allow those for any integer types. * standard wording is such that it does *NOT* have integer promotions applied to such bitfields, even if the size is smaller than int. Arguably, that's a hole in standard; in any case, both gcc and sparse *do* integer promotions on those, with the same behaviour as usual (value-preserving promotion). * for all bitfields we are told that they act as (signed or unsigned) integer types of specified width. That has interesting implications: unsigned long long f(unsigned long long n) { struct { unsigned long long n:33; } x = {n}; return x.n + x.n; } *must* be equivalent to (n + n) & 0x1ffffffff on all implementations that allow such bitfields. I.e. these suckers are not promoted to base type; they act as if we really head 33bit unsigned type, usual conversions in x.n + x.n left the result with that type and addition had been done within that type. gcc does it that way, we do not (x.n gets promoted to unsigned long long). AFAICS, sparse is wrong here; nothing to do about that, C99 is really not ambiguous in that area. HOWEVER, that's not the end of story. It's nice to say "it's an integer type of this width"; however, it is really not enough. What happens when we mix two such suckers with the same width? I.e. what about their ranks? gcc seems to do the following: when the width is equal to that of base type, treat the bitfield as equivalent to the base type. When the size is smaller, treat all bitfields with this width and this signedness as belonging to the same type. It leaves a corner case, though - what if the width *is* equal to that of a smaller normal type? It *is* possible even on amd64 - there's a 128bit integer type (can't get to it for bitfield without typedef due to cretinous syntax, but typedef unsigned __attribute__((mode(TI))) T; .... T x : 64; will get it for you). Apparently, that gets treated as equivalent of the lowest-rank standard type with that size, i.e. unsigned long in case of amd64. Fsck knows how stable that assumption would be... For now, it seems that they are careful of having such types only with the widths that do not overlap with those of standard types and having only one signed/unsigned pair for given size. BTW, with typeof() we *can* get to some of those types. We can't apply typeof to bitfield, but we can say struct {unsigned long long x:33;} x; typedef typeof(+x.x) __u33; and it will actually work as expected with gcc. Can do pointers to them, etc. Can't get smaller-than-int ones, but that's not particulary interesting due to integer promotions. I really wonder how well would sparse cope with that (allocation size > bit_size rounded to byte). -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html