// 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-conversion // RUN: %clang_cc1 %s -std=c++23 -triple=x86_64-apple-darwin10 -fsyntax-only -verify=expected,cpp -Wno-unused-value -Wno-unused-but-set-variable // 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-variable // 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-conversion typedef enum A { A_a, A_b, A_c, A_d } A; #ifdef __cplusplus #define DEFINE_ENUM(_Name, _Type, ...) enum class _Name : _Type { __VA_ARGS__ } ; #define ENUM_CLASS_REF(_Name, _Enum) _Name::_Enum #else #define DEFINE_ENUM(_Name, _Type, ...) typedef enum _Name : _Type { __VA_ARGS__ } _Name; #define ENUM_CLASS_REF(_Name, _Enum) _Enum #endif DEFINE_ENUM(B, int, B_a, B_b, B_c, B_d ); DEFINE_ENUM(C, unsigned, C_a, C_b, C_c, C_d ); DEFINE_ENUM(D, unsigned, D_a, D_b); // Not using templates here so we can more easily distinguish the responsible // party for each warning typedef struct S_A { A field1 : 1; // #S_A_field1 A field2 : 2; // #S_A_field2 A field3 : 8; // #S_A_field3 __attribute__((preferred_type(A))) // #preferred_S_A_field4 unsigned field4 : 1; // #S_A_field4 __attribute__((preferred_type(A))) unsigned field5 : 2; // #S_A_field5 __attribute__((preferred_type(A))) unsigned field6 : 8; // #S_A_field6 __attribute__((preferred_type(A))) // #preferred_S_A_field7 int field7 : 1; // #S_A_field7 __attribute__((preferred_type(A))) // #preferred_S_A_field8 int field8 : 2; // #S_A_field8 __attribute__((preferred_type(A))) int field9 : 8; // #S_A_field9 __attribute__((preferred_type(A))) D field10 : 1; // #S_A_field10 __attribute__((preferred_type(A))) // #preferred_S_A_field11 D field11 : 2; // #S_A_field11 __attribute__((preferred_type(A))) D field12 : 8; // #S_A_field12 } S_A; typedef struct S_B { B field1 : 1; // #S_B_field1 B field2 : 2; // #S_B_field2 B field3 : 8; // #S_B_field3 __attribute__((preferred_type(B))) // #preferred_S_B_field4 unsigned field4 : 1; // #S_B_field4 __attribute__((preferred_type(B))) unsigned field5 : 2; // #S_B_field5 __attribute__((preferred_type(B))) unsigned field6 : 8; // #S_B_field6 __attribute__((preferred_type(B))) // #preferred_S_B_field7 int field7 : 1; // #S_B_field7 __attribute__((preferred_type(B))) // #preferred_S_B_field8 int field8 : 2; // #S_B_field8 __attribute__((preferred_type(B))) int field9 : 8; // #S_B_field9 __attribute__((preferred_type(B))) D field10 : 1; // #S_B_field10 __attribute__((preferred_type(B))) // #preferred_S_B_field11 D field11 : 2; // #S_B_field11 __attribute__((preferred_type(B))) D field12 : 8; // #S_B_field12 } S_B; typedef struct S_C { C field1 : 1; // #S_C_field1 C field2 : 2; // #S_C_field2 C field3 : 8; // #S_C_field3 __attribute__((preferred_type(C))) // #preferred_S_C_field4 unsigned field4 : 1; // #S_C_field4 __attribute__((preferred_type(C))) unsigned field5 : 2; // #S_C_field5 __attribute__((preferred_type(C))) unsigned field6 : 8; // #S_C_field6 __attribute__((preferred_type(C))) // #preferred_S_C_field7 int field7 : 1; // #S_C_field7 __attribute__((preferred_type(C))) // #preferred_S_C_field8 int field8 : 2; // #S_C_field8 __attribute__((preferred_type(C))) int field9 : 8; // #S_C_field9 __attribute__((preferred_type(C))) D field10 : 1; // #S_C_field10 __attribute__((preferred_type(C))) // #preferred_S_C_field11 D field11 : 2; // #S_C_field11 __attribute__((preferred_type(C))) D field12 : 8; // #S_C_field12 } S_C; void read_enumA(S_A *s) { A x; x = s->field1; x = s->field2; x = s->field3; x = (A)s->field4; x = (A)s->field5; x = (A)s->field6; x = (A)s->field7; x = (A)s->field8; x = (A)s->field9; x = (A)s->field10; x = (A)s->field11; x = (A)s->field12; } void read_enumB(S_B *s) { B x; x = s->field1; x = s->field2; x = s->field3; x = (B)s->field4; x = (B)s->field5; x = (B)s->field6; x = (B)s->field7; x = (B)s->field8; x = (B)s->field9; x = (B)s->field10; x = (B)s->field11; x = (B)s->field12; } void read_enumC(S_C *s) { C x; x = s->field1; x = s->field2; x = s->field3; x = (C)s->field4; x = (C)s->field5; x = (C)s->field6; x = (C)s->field7; x = (C)s->field8; x = (C)s->field9; x = (C)s->field10; x = (C)s->field11; x = (C)s->field12; } void write_enumA(S_A *s, A x) { s->field1 = x; // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}} // bitfieldwarnings-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}} s->field2 = x; s->field3 = x; s->field4 = x; // bitfieldwarnings-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of 'A'}} // bitfieldwarnings-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}} s->field5 = x; s->field6 = x; s->field7 = x; // bitfieldwarnings-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of 'A'}} // bitfieldwarnings-note@#S_A_field7 {{widen this field to 2 bits to store all values of 'A'}} s->field8 = x; // bitfieldwarnings-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of 'A'}} // bitfieldwarnings-note@#S_A_field8 {{consider making the bit-field type unsigned}} s->field9 = x; s->field10 = (D)x; s->field11 = (D)x; s->field12 = (D)x; } void write_enumB(S_B *s, B x) { s->field1 = x; // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}} // bitfieldwarnings-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}} s->field2 = x; // bitfieldwarnings-warning@-1 {{signed bit-field 'field2' needs an extra bit to represent the largest positive enumerators of 'B'}} // bitfieldwarnings-note@#S_B_field2 {{consider making the bit-field type unsigned}} s->field3 = x; s->field4 = (unsigned)x; // expected-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}} // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}} // expected-note@#preferred_S_B_field4 {{preferred type for bit-field 'B' specified here}} s->field5 = (unsigned)x; s->field6 = (unsigned)x; s->field7 = (int)x; // expected-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}} // expected-note@#S_B_field7 {{widen this field to 2 bits to store all values of 'B'}} // expected-note@#preferred_S_B_field7 {{preferred type for bit-field 'B' specified here}} s->field8 = (int)x; // expected-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}} // expected-note@#S_B_field8 {{consider making the bit-field type unsigned}} // expected-note@#preferred_S_B_field8 {{preferred type for bit-field 'B' specified here}} s->field9 = (int)x; s->field10 = (D)x; s->field11 = (D)x; s->field12 = (D)x; } void write_enumC(S_C *s, C x) { s->field1 = x; // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}} // bitfieldwarnings-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}} s->field2 = x; s->field3 = x; s->field4 = (unsigned)x; // expected-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}} // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}} // expected-note@#preferred_S_C_field4 {{preferred type for bit-field 'C' specified here}} s->field5 = (unsigned)x; s->field6 = (unsigned)x; s->field7 = (int)x; // expected-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}} // expected-note@#S_C_field7 {{widen this field to 2 bits to store all values of 'C'}} // expected-note@#preferred_S_C_field7 {{preferred type for bit-field 'C' specified here}} s->field8 = (int)x; // expected-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}} // expected-note@#S_C_field8 {{consider making the bit-field type unsigned}} // expected-note@#preferred_S_C_field8 {{preferred type for bit-field 'C' specified here}} s->field9 = (int)x; s->field10 = (D)x; s->field11 = (D)x; s->field12 = (D)x; } void write_enum_intA(struct S_A *s, int x) { s->field1 = (A)x; // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'A'}} // bitfieldwarnings-note@#S_A_field1 {{widen this field to 2 bits to store all values of 'A'}} s->field2 = (A)x; s->field3 = (A)x; s->field4 = x; // expected-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'A'}} // expected-note@#S_A_field4 {{widen this field to 2 bits to store all values of 'A'}} // expected-note@#preferred_S_A_field4 {{preferred type for bit-field 'A' specified here}} s->field5 = x; s->field6 = x; s->field7 = x; // expected-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'A'}} // expected-note@#S_A_field7 {{widen this field to 2 bits to store all values of 'A'}} // expected-note@#preferred_S_A_field7 {{preferred type for bit-field 'A' specified here}} s->field8 = x; // expected-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'A'}} // expected-note@#S_A_field8 {{consider making the bit-field type unsigned}} // expected-note@#preferred_S_A_field8 {{preferred type for bit-field 'A' specified here}} s->field9 = x; s->field10 = (D)x; s->field11 = (D)x; s->field12 = (D)x; } void write_enum_intB(struct S_B *s, int x) { s->field1 = (B)x; // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'B'}} // bitfieldwarnings-note@#S_B_field1 {{widen this field to 2 bits to store all values of 'B'}} s->field2 = (B)x; // bitfieldwarnings-warning@-1 {{signed bit-field 'field2' needs an extra bit to represent the largest positive enumerators of 'B'}} // bitfieldwarnings-note@#S_B_field2 {{consider making the bit-field type unsigned}} s->field3 = (B)x; s->field4 = x; // expected-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'B'}} // expected-note@#S_B_field4 {{widen this field to 2 bits to store all values of 'B'}} // expected-note@#preferred_S_B_field4 {{preferred type for bit-field 'B' specified here}} s->field5 = x; s->field6 = x; s->field7 = x; // expected-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'B'}} // expected-note@#S_B_field7 {{widen this field to 2 bits to store all values of 'B'}} // expected-note@#preferred_S_B_field7 {{preferred type for bit-field 'B' specified here}} s->field8 = x; // expected-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'B'}} // expected-note@#S_B_field8 {{consider making the bit-field type unsigned}} // expected-note@#preferred_S_B_field8 {{preferred type for bit-field 'B' specified here}} s->field9 = x; s->field10 = (D)x; s->field11 = (D)x; s->field12 = (D)x; } void write_enum_intC(struct S_C *s, int x) { s->field1 = (C)x; // bitfieldwarnings-warning@-1 {{bit-field 'field1' is not wide enough to store all enumerators of 'C'}} // bitfieldwarnings-note@#S_C_field1 {{widen this field to 2 bits to store all values of 'C'}} s->field2 = (C)x; s->field3 = (C)x; s->field4 = x; // expected-warning@-1 {{bit-field 'field4' is not wide enough to store all enumerators of preferred type 'C'}} // expected-note@#S_C_field4 {{widen this field to 2 bits to store all values of 'C'}} // expected-note@#preferred_S_C_field4 {{preferred type for bit-field 'C' specified here}} s->field5 = x; s->field6 = x; s->field7 = x; // expected-warning@-1 {{bit-field 'field7' is not wide enough to store all enumerators of preferred type 'C'}} // expected-note@#S_C_field7 {{widen this field to 2 bits to store all values of 'C'}} // expected-note@#preferred_S_C_field7 {{preferred type for bit-field 'C' specified here}} s->field8 = x; // expected-warning@-1 {{signed bit-field 'field8' needs an extra bit to represent the largest positive enumerators of preferred type 'C'}} // expected-note@#S_C_field8 {{consider making the bit-field type unsigned}} // expected-note@#preferred_S_C_field8 {{preferred type for bit-field 'C' specified here}} s->field9 = x; s->field10 = (D)x; s->field11 = (D)x; s->field12 = (D)x; } void write_low_constantA(S_A *s) { s->field1 = A_a; s->field2 = A_a; s->field3 = A_a; s->field4 = A_a; s->field5 = A_a; s->field6 = A_a; s->field7 = A_a; s->field8 = A_a; s->field9 = A_a; s->field10 = (D)A_a; s->field11 = (D)A_a; s->field12 = (D)A_a; }; void write_low_constantB(S_B *s) { s->field1 = ENUM_CLASS_REF(B, B_a); s->field2 = ENUM_CLASS_REF(B, B_a); s->field3 = ENUM_CLASS_REF(B, B_a); s->field4 = (unsigned)ENUM_CLASS_REF(B, B_a); s->field5 = (unsigned)ENUM_CLASS_REF(B, B_a); s->field6 = (unsigned)ENUM_CLASS_REF(B, B_a); s->field7 = (int)ENUM_CLASS_REF(B, B_a); s->field8 = (int)ENUM_CLASS_REF(B, B_a); s->field9 = (int)ENUM_CLASS_REF(B, B_a); s->field10 = (D)ENUM_CLASS_REF(B, B_a); s->field11 = (D)ENUM_CLASS_REF(B, B_a); s->field12 = (D)ENUM_CLASS_REF(B, B_a); }; void write_low_constantC(S_C *s) { s->field1 = ENUM_CLASS_REF(C, C_a); s->field2 = ENUM_CLASS_REF(C, C_a); s->field3 = ENUM_CLASS_REF(C, C_a); s->field4 = (unsigned)ENUM_CLASS_REF(C, C_a); s->field5 = (unsigned)ENUM_CLASS_REF(C, C_a); s->field6 = (unsigned)ENUM_CLASS_REF(C, C_a); s->field7 = (int)ENUM_CLASS_REF(C, C_a); s->field8 = (int)ENUM_CLASS_REF(C, C_a); s->field9 = (int)ENUM_CLASS_REF(C, C_a); s->field10 = (D)ENUM_CLASS_REF(C, C_a); s->field11 = (D)ENUM_CLASS_REF(C, C_a); s->field12 = (D)ENUM_CLASS_REF(C, C_a); }; void write_high_constantA(S_A *s) { s->field1 = A_d; // cpp-warning@-1 {{implicit truncation from 'A' to bit-field changes value from 3 to 1}} // c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}} s->field2 = A_d; s->field3 = A_d; s->field4 = A_d; // cpp-warning@-1 {{implicit truncation from 'A' to bit-field changes value from 3 to 1}} // c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to 1}} s->field5 = A_d; s->field6 = A_d; s->field7 = A_d; // cpp-warning@-1 {{implicit truncation from 'A' to bit-field changes value from 3 to -1}} // c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}} s->field8 = A_d; // cpp-warning@-1 {{implicit truncation from 'A' to bit-field changes value from 3 to -1}} // c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}} s->field9 = A_d; s->field10 = (D)A_d; // cpp-warning@-1 {{implicit truncation from 'D' to bit-field changes value from 3 to 1}} // c-warning@-2 {{implicit truncation from 'D' (aka 'enum D') to bit-field changes value from 3 to 1}} s->field11 = (D)A_d; s->field12 = (D)A_d; }; void write_high_constantB(S_B *s) { s->field1 = ENUM_CLASS_REF(B, B_d); // cpp-warning@-1 {{implicit truncation from 'B' to bit-field changes value from 3 to 1}} // c-warning@-2 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}} s->field2 = ENUM_CLASS_REF(B, B_d); // c-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}} s->field3 = ENUM_CLASS_REF(B, B_d); s->field4 = (unsigned)ENUM_CLASS_REF(B, B_d); // expected-warning@-1 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}} s->field5 = (unsigned)ENUM_CLASS_REF(B, B_d); s->field6 = (unsigned)ENUM_CLASS_REF(B, B_d); s->field7 = (int)ENUM_CLASS_REF(B, B_d); // expected-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}} s->field8 = (int)ENUM_CLASS_REF(B, B_d); // expected-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}} s->field9 = (int)ENUM_CLASS_REF(B, B_d); }; void write_high_constantC(S_C *s) { s->field1 = ENUM_CLASS_REF(C, C_d); // cpp-warning@-1 {{implicit truncation from 'C' to bit-field changes value from 3 to 1}} // c-warning@-2 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}} s->field2 = ENUM_CLASS_REF(C, C_d); s->field3 = ENUM_CLASS_REF(C, C_d); s->field4 = (unsigned)ENUM_CLASS_REF(C, C_d); // expected-warning@-1 {{implicit truncation from 'unsigned int' to bit-field changes value from 3 to 1}} s->field5 = (unsigned)ENUM_CLASS_REF(C, C_d); s->field6 = (unsigned)ENUM_CLASS_REF(C, C_d); s->field7 = (int)ENUM_CLASS_REF(C, C_d); // expected-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}} s->field8 = (int)ENUM_CLASS_REF(C, C_d); // expected-warning@-1 {{implicit truncation from 'int' to bit-field changes value from 3 to -1}} s->field9 = (int)ENUM_CLASS_REF(C, C_d); };