1 | // RUN: %clang_cc1 -triple %itanium_abi_triple -verify -fsyntax-only -std=c11 -Wassign-enum %s |
2 | |
3 | enum __attribute__((flag_enum)) flag { |
4 | ea = 0x1, |
5 | eb = 0x2, |
6 | ec = 0x8, |
7 | }; |
8 | |
9 | enum __attribute__((flag_enum)) flag2 { |
10 | ga = 0x1, |
11 | gb = 0x4, |
12 | |
13 | gc = 0x5, // no-warning |
14 | gd = 0x7, // expected-warning {{enumeration value 'gd' is out of range}} |
15 | ge = ~0x2, // expected-warning {{enumeration value 'ge' is out of range}} |
16 | gf = ~0x4, // no-warning |
17 | gg = ~0x1, // no-warning |
18 | gh = ~0x5, // no-warning |
19 | gi = ~0x11, // expected-warning {{enumeration value 'gi' is out of range}} |
20 | }; |
21 | |
22 | enum __attribute__((flag_enum)) flag3 { |
23 | fa = 0x1, |
24 | fb = ~0x1u, // no-warning |
25 | }; |
26 | |
27 | // What happens here is that ~0x2 is negative, and so the enum must be signed. |
28 | // But ~0x1u is unsigned and has the high bit set, so the enum must be 64-bit. |
29 | // The result is that ~0x1u does not have high bits set, and so it is considered |
30 | // to be an invalid value. See Sema::IsValueInFlagEnum in SemaDecl.cpp for more |
31 | // discussion. |
32 | enum __attribute__((flag_enum)) flag4 { |
33 | ha = 0x1, |
34 | hb = 0x2, |
35 | |
36 | hc = ~0x1u, // expected-warning {{enumeration value 'hc' is out of range}} |
37 | hd = ~0x2, // no-warning |
38 | }; |
39 | |
40 | void f(void) { |
41 | enum flag e = 0; // no-warning |
42 | e = 0x1; // no-warning |
43 | e = 0x3; // no-warning |
44 | e = 0xa; // no-warning |
45 | e = 0x4; // expected-warning {{integer constant not in range of enumerated type}} |
46 | e = 0xf; // expected-warning {{integer constant not in range of enumerated type}} |
47 | e = ~0; // no-warning |
48 | e = ~0x1; // no-warning |
49 | e = ~0x2; // no-warning |
50 | e = ~0x3; // no-warning |
51 | e = ~0x4; // expected-warning {{integer constant not in range of enumerated type}} |
52 | |
53 | switch (e) { |
54 | case 0: break; // no-warning |
55 | case 0x1: break; // no-warning |
56 | case 0x3: break; // no-warning |
57 | case 0xa: break; // no-warning |
58 | case 0x4: break; // expected-warning {{case value not in enumerated type}} |
59 | case 0xf: break; // expected-warning {{case value not in enumerated type}} |
60 | case ~0: break; // expected-warning {{case value not in enumerated type}} |
61 | case ~0x1: break; // expected-warning {{case value not in enumerated type}} |
62 | case ~0x2: break; // expected-warning {{case value not in enumerated type}} |
63 | case ~0x3: break; // expected-warning {{case value not in enumerated type}} |
64 | case ~0x4: break; // expected-warning {{case value not in enumerated type}} |
65 | default: break; |
66 | } |
67 | |
68 | enum flag2 f = ~0x1; // no-warning |
69 | f = ~0x1u; // no-warning |
70 | |
71 | enum flag4 h = ~0x1; // no-warning |
72 | h = ~0x1u; // expected-warning {{integer constant not in range of enumerated type}} |
73 | } |
74 | |