412 lines · cpp
1// RUN: %clang_cc1 %s -std=c++23 -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,bitfieldwarnings,cpp -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion2// RUN: %clang_cc1 %s -std=c++23 -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,cpp -Wno-unused-value -Wno-unused-but-set-variable3 4// RUN: %clang_cc1 %s -x c -std=c23 -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,c -Wno-unused-value -Wno-unused-but-set-variable5// RUN: %clang_cc1 %s -x c -std=c23 -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,bitfieldwarnings,c -Wno-unused-value -Wno-unused-but-set-variable -Wbitfield-width -Wbitfield-enum-conversion6 7 8typedef enum A {9 A_a,10 A_b,11 A_c,12 A_d13} A;14 15#ifdef __cplusplus16#define DEFINE_ENUM(_Name, _Type, ...) enum class _Name : _Type { __VA_ARGS__ } ;17#define ENUM_CLASS_REF(_Name, _Enum) _Name::_Enum18#else19#define DEFINE_ENUM(_Name, _Type, ...) typedef enum _Name : _Type { __VA_ARGS__ } _Name;20#define ENUM_CLASS_REF(_Name, _Enum) _Enum21#endif22 23DEFINE_ENUM(B, int, B_a, B_b, B_c, B_d );24DEFINE_ENUM(C, unsigned, C_a, C_b, C_c, C_d );25DEFINE_ENUM(D, unsigned, D_a, D_b);26 27// Not using templates here so we can more easily distinguish the responsible28// party for each warning29 30typedef struct S_A {31 A field1 : 1; // #S_A_field132 A field2 : 2; // #S_A_field233 A field3 : 8; // #S_A_field334 __attribute__((preferred_type(A))) // #preferred_S_A_field435 unsigned field4 : 1; // #S_A_field436 __attribute__((preferred_type(A)))37 unsigned field5 : 2; // #S_A_field538 __attribute__((preferred_type(A)))39 unsigned field6 : 8; // #S_A_field640 __attribute__((preferred_type(A))) // #preferred_S_A_field741 int field7 : 1; // #S_A_field742 __attribute__((preferred_type(A))) // #preferred_S_A_field843 int field8 : 2; // #S_A_field844 __attribute__((preferred_type(A)))45 int field9 : 8; // #S_A_field946 __attribute__((preferred_type(A)))47 D field10 : 1; // #S_A_field1048 __attribute__((preferred_type(A))) // #preferred_S_A_field1149 D field11 : 2; // #S_A_field1150 __attribute__((preferred_type(A)))51 D field12 : 8; // #S_A_field1252} S_A;53 54typedef struct S_B {55 B field1 : 1; // #S_B_field156 B field2 : 2; // #S_B_field257 B field3 : 8; // #S_B_field358 __attribute__((preferred_type(B))) // #preferred_S_B_field459 unsigned field4 : 1; // #S_B_field460 __attribute__((preferred_type(B)))61 unsigned field5 : 2; // #S_B_field562 __attribute__((preferred_type(B)))63 unsigned field6 : 8; // #S_B_field664 __attribute__((preferred_type(B))) // #preferred_S_B_field765 int field7 : 1; // #S_B_field766 __attribute__((preferred_type(B))) // #preferred_S_B_field867 int field8 : 2; // #S_B_field868 __attribute__((preferred_type(B)))69 int field9 : 8; // #S_B_field970 __attribute__((preferred_type(B)))71 D field10 : 1; // #S_B_field1072 __attribute__((preferred_type(B))) // #preferred_S_B_field1173 D field11 : 2; // #S_B_field1174 __attribute__((preferred_type(B)))75 D field12 : 8; // #S_B_field1276} S_B;77 78typedef struct S_C {79 C field1 : 1; // #S_C_field180 C field2 : 2; // #S_C_field281 C field3 : 8; // #S_C_field382 __attribute__((preferred_type(C))) // #preferred_S_C_field483 unsigned field4 : 1; // #S_C_field484 __attribute__((preferred_type(C)))85 unsigned field5 : 2; // #S_C_field586 __attribute__((preferred_type(C)))87 unsigned field6 : 8; // #S_C_field688 __attribute__((preferred_type(C))) // #preferred_S_C_field789 int field7 : 1; // #S_C_field790 __attribute__((preferred_type(C))) // #preferred_S_C_field891 int field8 : 2; // #S_C_field892 __attribute__((preferred_type(C)))93 int field9 : 8; // #S_C_field994 __attribute__((preferred_type(C)))95 D field10 : 1; // #S_C_field1096 __attribute__((preferred_type(C))) // #preferred_S_C_field1197 D field11 : 2; // #S_C_field1198 __attribute__((preferred_type(C)))99 D field12 : 8; // #S_C_field12100} S_C;101 102void read_enumA(S_A *s) {103 A x;104 x = s->field1;105 x = s->field2;106 x = s->field3;107 x = (A)s->field4;108 x = (A)s->field5;109 x = (A)s->field6;110 x = (A)s->field7;111 x = (A)s->field8;112 x = (A)s->field9;113 x = (A)s->field10;114 x = (A)s->field11;115 x = (A)s->field12;116}117 118void read_enumB(S_B *s) {119 B x;120 x = s->field1;121 x = s->field2;122 x = s->field3;123 x = (B)s->field4;124 x = (B)s->field5;125 x = (B)s->field6;126 x = (B)s->field7;127 x = (B)s->field8;128 x = (B)s->field9;129 x = (B)s->field10;130 x = (B)s->field11;131 x = (B)s->field12;132}133 134void read_enumC(S_C *s) {135 C x;136 x = s->field1;137 x = s->field2;138 x = s->field3;139 x = (C)s->field4;140 x = (C)s->field5;141 x = (C)s->field6;142 x = (C)s->field7;143 x = (C)s->field8;144 x = (C)s->field9;145 x = (C)s->field10;146 x = (C)s->field11;147 x = (C)s->field12;148}149 150void write_enumA(S_A *s, A x) {151 s->field1 = x;152 // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}}153 // bitfieldwarnings-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}}154 s->field2 = x;155 s->field3 = x;156 s->field4 = x;157 // bitfieldwarnings-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of 'A'}}158 // bitfieldwarnings-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}}159 s->field5 = x;160 s->field6 = x;161 s->field7 = x;162 // bitfieldwarnings-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of 'A'}}163 // bitfieldwarnings-note@#S_A_field7 {{widen this field to 2 bits to store all values of 'A'}}164 s->field8 = x;165 // bitfieldwarnings-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of 'A'}}166 // bitfieldwarnings-note@#S_A_field8 {{consider making the bit-field type unsigned}}167 s->field9 = x;168 s->field10 = (D)x;169 s->field11 = (D)x;170 s->field12 = (D)x;171}172 173void write_enumB(S_B *s, B x) {174 s->field1 = x;175 // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}}176 // bitfieldwarnings-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}}177 s->field2 = x;178 // bitfieldwarnings-warning@-1 {{signed bit-field 'field2' needs an extra bit to represent the largest positive enumerators of 'B'}}179 // bitfieldwarnings-note@#S_B_field2 {{consider making the bit-field type unsigned}}180 s->field3 = x;181 s->field4 = (unsigned)x;182 // expected-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}183 // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}}184 // expected-note@#preferred_S_B_field4 {{preferred type for bit-field 'B' specified here}}185 s->field5 = (unsigned)x;186 s->field6 = (unsigned)x;187 s->field7 = (int)x;188 // expected-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}189 // expected-note@#S_B_field7 {{widen this field to 2 bits to store all values of 'B'}}190 // expected-note@#preferred_S_B_field7 {{preferred type for bit-field 'B' specified here}}191 s->field8 = (int)x;192 // expected-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}193 // expected-note@#S_B_field8 {{consider making the bit-field type unsigned}}194 // expected-note@#preferred_S_B_field8 {{preferred type for bit-field 'B' specified here}}195 s->field9 = (int)x;196 s->field10 = (D)x;197 s->field11 = (D)x;198 s->field12 = (D)x;199}200 201void write_enumC(S_C *s, C x) {202 s->field1 = x;203 // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}204 // bitfieldwarnings-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}}205 s->field2 = x;206 s->field3 = x;207 s->field4 = (unsigned)x;208 // expected-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}209 // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}}210 // expected-note@#preferred_S_C_field4 {{preferred type for bit-field 'C' specified here}}211 s->field5 = (unsigned)x;212 s->field6 = (unsigned)x;213 s->field7 = (int)x;214 // expected-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}215 // expected-note@#S_C_field7 {{widen this field to 2 bits to store all values of 'C'}}216 // expected-note@#preferred_S_C_field7 {{preferred type for bit-field 'C' specified here}}217 s->field8 = (int)x;218 // expected-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}219 // expected-note@#S_C_field8 {{consider making the bit-field type unsigned}}220 // expected-note@#preferred_S_C_field8 {{preferred type for bit-field 'C' specified here}}221 s->field9 = (int)x;222 s->field10 = (D)x;223 s->field11 = (D)x;224 s->field12 = (D)x;225}226 227void write_enum_intA(struct S_A *s, int x) {228 s->field1 = (A)x;229 // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}}230 // bitfieldwarnings-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}}231 s->field2 = (A)x;232 s->field3 = (A)x;233 s->field4 = x;234 // expected-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'A'}}235 // expected-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}}236 // expected-note@#preferred_S_A_field4 {{preferred type for bit-field 'A' specified here}}237 s->field5 = x;238 s->field6 = x;239 s->field7 = x;240 // expected-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'A'}}241 // expected-note@#S_A_field7 {{widen this field to 2 bits to store all values of 'A'}}242 // expected-note@#preferred_S_A_field7 {{preferred type for bit-field 'A' specified here}}243 s->field8 = x;244 // expected-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}}245 // expected-note@#S_A_field8 {{consider making the bit-field type unsigned}}246 // expected-note@#preferred_S_A_field8 {{preferred type for bit-field 'A' specified here}}247 s->field9 = x;248 s->field10 = (D)x;249 s->field11 = (D)x;250 s->field12 = (D)x;251}252 253void write_enum_intB(struct S_B *s, int x) {254 s->field1 = (B)x;255 // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}}256 // bitfieldwarnings-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}}257 s->field2 = (B)x;258 // bitfieldwarnings-warning@-1 {{signed bit-field 'field2' needs an extra bit to represent the largest positive enumerators of 'B'}}259 // bitfieldwarnings-note@#S_B_field2 {{consider making the bit-field type unsigned}}260 s->field3 = (B)x;261 s->field4 = x;262 // expected-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}}263 // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}}264 // expected-note@#preferred_S_B_field4 {{preferred type for bit-field 'B' specified here}}265 s->field5 = x;266 s->field6 = x;267 s->field7 = x;268 // expected-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}}269 // expected-note@#S_B_field7 {{widen this field to 2 bits to store all values of 'B'}}270 // expected-note@#preferred_S_B_field7 {{preferred type for bit-field 'B' specified here}}271 s->field8 = x;272 // expected-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}}273 // expected-note@#S_B_field8 {{consider making the bit-field type unsigned}}274 // expected-note@#preferred_S_B_field8 {{preferred type for bit-field 'B' specified here}}275 s->field9 = x;276 s->field10 = (D)x;277 s->field11 = (D)x;278 s->field12 = (D)x;279}280 281void write_enum_intC(struct S_C *s, int x) {282 s->field1 = (C)x;283 // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}}284 // bitfieldwarnings-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}}285 s->field2 = (C)x;286 s->field3 = (C)x;287 s->field4 = x;288 // expected-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}}289 // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}}290 // expected-note@#preferred_S_C_field4 {{preferred type for bit-field 'C' specified here}}291 s->field5 = x;292 s->field6 = x;293 s->field7 = x;294 // expected-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}}295 // expected-note@#S_C_field7 {{widen this field to 2 bits to store all values of 'C'}}296 // expected-note@#preferred_S_C_field7 {{preferred type for bit-field 'C' specified here}}297 s->field8 = x;298 // expected-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}}299 // expected-note@#S_C_field8 {{consider making the bit-field type unsigned}}300 // expected-note@#preferred_S_C_field8 {{preferred type for bit-field 'C' specified here}}301 s->field9 = x;302 s->field10 = (D)x;303 s->field11 = (D)x;304 s->field12 = (D)x;305}306 307void write_low_constantA(S_A *s) {308 s->field1 = A_a;309 s->field2 = A_a;310 s->field3 = A_a;311 s->field4 = A_a;312 s->field5 = A_a;313 s->field6 = A_a;314 s->field7 = A_a;315 s->field8 = A_a;316 s->field9 = A_a;317 s->field10 = (D)A_a;318 s->field11 = (D)A_a;319 s->field12 = (D)A_a;320};321 322void write_low_constantB(S_B *s) {323 s->field1 = ENUM_CLASS_REF(B, B_a);324 s->field2 = ENUM_CLASS_REF(B, B_a);325 s->field3 = ENUM_CLASS_REF(B, B_a);326 s->field4 = (unsigned)ENUM_CLASS_REF(B, B_a);327 s->field5 = (unsigned)ENUM_CLASS_REF(B, B_a);328 s->field6 = (unsigned)ENUM_CLASS_REF(B, B_a);329 s->field7 = (int)ENUM_CLASS_REF(B, B_a);330 s->field8 = (int)ENUM_CLASS_REF(B, B_a);331 s->field9 = (int)ENUM_CLASS_REF(B, B_a);332 s->field10 = (D)ENUM_CLASS_REF(B, B_a);333 s->field11 = (D)ENUM_CLASS_REF(B, B_a);334 s->field12 = (D)ENUM_CLASS_REF(B, B_a);335};336 337void write_low_constantC(S_C *s) {338 s->field1 = ENUM_CLASS_REF(C, C_a);339 s->field2 = ENUM_CLASS_REF(C, C_a);340 s->field3 = ENUM_CLASS_REF(C, C_a);341 s->field4 = (unsigned)ENUM_CLASS_REF(C, C_a);342 s->field5 = (unsigned)ENUM_CLASS_REF(C, C_a);343 s->field6 = (unsigned)ENUM_CLASS_REF(C, C_a);344 s->field7 = (int)ENUM_CLASS_REF(C, C_a);345 s->field8 = (int)ENUM_CLASS_REF(C, C_a);346 s->field9 = (int)ENUM_CLASS_REF(C, C_a);347 s->field10 = (D)ENUM_CLASS_REF(C, C_a);348 s->field11 = (D)ENUM_CLASS_REF(C, C_a);349 s->field12 = (D)ENUM_CLASS_REF(C, C_a);350};351 352void write_high_constantA(S_A *s) {353 s->field1 = A_d;354 // cpp-warning@-1 {{implicit truncation from 'A' to bit-field changes value from 3 to 1}}355 // c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}356 s->field2 = A_d;357 s->field3 = A_d;358 s->field4 = A_d;359 // cpp-warning@-1 {{implicit truncation from 'A' to bit-field changes value from 3 to 1}}360 // c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}}361 s->field5 = A_d;362 s->field6 = A_d;363 s->field7 = A_d;364 // cpp-warning@-1 {{implicit truncation from 'A' to bit-field changes value from 3 to -1}}365 // c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}366 s->field8 = A_d;367 // cpp-warning@-1 {{implicit truncation from 'A' to bit-field changes value from 3 to -1}}368 // c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}369 s->field9 = A_d;370 s->field10 = (D)A_d;371 // cpp-warning@-1 {{implicit truncation from 'D' to bit-field changes value from 3 to 1}}372 // c-warning@-2 {{implicit truncation from 'D' (aka 'enum D') to bit-field changes value from 3 to 1}}373 s->field11 = (D)A_d;374 s->field12 = (D)A_d;375};376 377void write_high_constantB(S_B *s) {378 s->field1 = ENUM_CLASS_REF(B, B_d);379 // cpp-warning@-1 {{implicit truncation from 'B' to bit-field changes value from 3 to 1}}380 // c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}381 s->field2 = ENUM_CLASS_REF(B, B_d);382 // c-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}383 s->field3 = ENUM_CLASS_REF(B, B_d);384 s->field4 = (unsigned)ENUM_CLASS_REF(B, B_d);385 // expected-warning@-1 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}}386 s->field5 = (unsigned)ENUM_CLASS_REF(B, B_d);387 s->field6 = (unsigned)ENUM_CLASS_REF(B, B_d);388 s->field7 = (int)ENUM_CLASS_REF(B, B_d);389 // expected-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}390 s->field8 = (int)ENUM_CLASS_REF(B, B_d);391 // expected-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}392 s->field9 = (int)ENUM_CLASS_REF(B, B_d);393};394 395 396void write_high_constantC(S_C *s) {397 s->field1 = ENUM_CLASS_REF(C, C_d);398 // cpp-warning@-1 {{implicit truncation from 'C' to bit-field changes value from 3 to 1}}399 // c-warning@-2 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}}400 s->field2 = ENUM_CLASS_REF(C, C_d);401 s->field3 = ENUM_CLASS_REF(C, C_d);402 s->field4 = (unsigned)ENUM_CLASS_REF(C, C_d);403 // expected-warning@-1 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}}404 s->field5 = (unsigned)ENUM_CLASS_REF(C, C_d);405 s->field6 = (unsigned)ENUM_CLASS_REF(C, C_d);406 s->field7 = (int)ENUM_CLASS_REF(C, C_d);407 // expected-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}408 s->field8 = (int)ENUM_CLASS_REF(C, C_d);409 // expected-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}}410 s->field9 = (int)ENUM_CLASS_REF(C, C_d);411};412