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