1*c85f09ccSJohn Levon // For enum's underlying/compatible type: 2*c85f09ccSJohn Levon // std C: unspecified 3*c85f09ccSJohn Levon // GCC: 'unsigned int' if no negative values, 4*c85f09ccSJohn Levon // otherwise 'int' (see GCC manul 4.9). 5*c85f09ccSJohn Levon // But also accept ulong, long 6*c85f09ccSJohn Levon // For the type of the enumerators: 7*c85f09ccSJohn Levon // std C: 'int' 8*c85f09ccSJohn Levon // GCC: 'int' if the value fit in a 'int' 9*c85f09ccSJohn Levon // otherwise same as the enum underlying type? 10*c85f09ccSJohn Levon // 11*c85f09ccSJohn Levon // The following tests match GCC's choices 12*c85f09ccSJohn Levon 13*c85f09ccSJohn Levon #define is_unsigned(X) ((typeof(X))-1 > 0) 14*c85f09ccSJohn Levon 15*c85f09ccSJohn Levon enum u { 16*c85f09ccSJohn Levon U = 1U, // fit in 'int' 17*c85f09ccSJohn Levon // no negatives 18*c85f09ccSJohn Levon }; 19*c85f09ccSJohn Levon _Static_assert(sizeof(enum u) == sizeof(int), "size"); 20*c85f09ccSJohn Levon _Static_assert(is_unsigned(enum u), "enum u"); 21*c85f09ccSJohn Levon _Static_assert(is_unsigned(U) == 0, "value U"); // fail 22*c85f09ccSJohn Levon 23*c85f09ccSJohn Levon enum v { 24*c85f09ccSJohn Levon V = __INT_MAX__ + 1U, // doesn't fit in 'int' 25*c85f09ccSJohn Levon // no negatives 26*c85f09ccSJohn Levon }; 27*c85f09ccSJohn Levon _Static_assert(sizeof(enum v) == sizeof(int), "size"); 28*c85f09ccSJohn Levon _Static_assert(is_unsigned(enum v), "enum v"); 29*c85f09ccSJohn Levon _Static_assert(is_unsigned(V) == 1, "value V"); 30*c85f09ccSJohn Levon 31*c85f09ccSJohn Levon enum w { 32*c85f09ccSJohn Levon W = __LONG_MAX__ + 1UL, // doesn't fit in 'long' 33*c85f09ccSJohn Levon }; 34*c85f09ccSJohn Levon _Static_assert(sizeof(enum w) == sizeof(long), "size"); 35*c85f09ccSJohn Levon _Static_assert(is_unsigned(enum w), "enum w"); 36*c85f09ccSJohn Levon _Static_assert(is_unsigned(W) == 1, "value W"); 37*c85f09ccSJohn Levon 38*c85f09ccSJohn Levon enum x { 39*c85f09ccSJohn Levon A = 1, // fit in 'int' 40*c85f09ccSJohn Levon B = 0x100000000UL, // doesn't fit in int 41*c85f09ccSJohn Levon }; 42*c85f09ccSJohn Levon _Static_assert(sizeof(enum x) == sizeof(long), "size"); 43*c85f09ccSJohn Levon _Static_assert(is_unsigned(enum x), "enum x"); 44*c85f09ccSJohn Levon _Static_assert(sizeof(A) == sizeof(int), "size A"); // fail 45*c85f09ccSJohn Levon _Static_assert(is_unsigned(A) == 0, "enum A"); // fail 46*c85f09ccSJohn Levon _Static_assert(sizeof(B) == sizeof(long), "size B"); 47*c85f09ccSJohn Levon _Static_assert(is_unsigned(B) == 1, "enum B"); 48*c85f09ccSJohn Levon 49*c85f09ccSJohn Levon enum y { 50*c85f09ccSJohn Levon C = 1, // fit in 'int' 51*c85f09ccSJohn Levon D = 0x100000000L, // doesn't fit in int 52*c85f09ccSJohn Levon }; 53*c85f09ccSJohn Levon _Static_assert(sizeof(enum y) == sizeof(long), "size"); 54*c85f09ccSJohn Levon _Static_assert(is_unsigned(enum y), "enum y"); 55*c85f09ccSJohn Levon _Static_assert(sizeof(C) == sizeof(int), "size C"); // fail 56*c85f09ccSJohn Levon _Static_assert(is_unsigned(C) == 0, "enum C"); // fail 57*c85f09ccSJohn Levon _Static_assert(sizeof(D) == sizeof(long), "size D"); 58*c85f09ccSJohn Levon _Static_assert(is_unsigned(D) == 1, "enum D"); 59*c85f09ccSJohn Levon 60*c85f09ccSJohn Levon /* 61*c85f09ccSJohn Levon * check-name: enum-sign-gcc 62*c85f09ccSJohn Levon * check-command: sparse -m64 $file 63*c85f09ccSJohn Levon * check-assert: sizeof(long) == 8 64*c85f09ccSJohn Levon */ 65