| |
| // RUN: %clang_cc1 -fsyntax-only -Wms-bitfield-padding -verify -triple armv8 -std=c++23 %s |
| // RUN: %clang_cc1 -fsyntax-only -DMS_BITFIELDS -mms-bitfields -verify=msbitfields -triple armv8-apple-macos10.15 -std=c++23 %s |
| |
| // msbitfields-no-diagnostics |
| |
| enum Enum1 { Enum1_A, Enum1_B }; |
| enum Enum2 { Enum2_A, Enum2_B }; |
| |
| enum class EnumU32_1 : unsigned { A, B }; |
| enum class EnumU32_2 : unsigned { A, B }; |
| enum class EnumU64 : unsigned long long { A, B }; |
| enum class EnumI32 : int { A, B }; |
| enum class EnumU8 : unsigned char { A, B }; |
| enum class EnumI8 : char { A, B }; |
| enum class EnumU16 : unsigned short { A, B }; |
| enum class EnumI16 : short { A, B }; |
| |
| struct A { |
| unsigned int a : 15; |
| unsigned int b : 15; |
| }; |
| static_assert(sizeof(A) == 4); |
| |
| struct B { |
| unsigned int a : 15; |
| int b : 15; |
| }; |
| static_assert(sizeof(B) == 4); |
| |
| struct C { |
| unsigned int a : 15; |
| int b : 15; |
| }; |
| static_assert(sizeof(C) == 4); |
| |
| struct D { |
| Enum1 a : 15; |
| Enum1 b : 15; |
| }; |
| static_assert(sizeof(D) == 4); |
| |
| struct E { |
| Enum1 a : 15; |
| Enum2 b : 15; |
| }; |
| static_assert(sizeof(E) == 4); |
| |
| struct F { |
| EnumU32_1 a : 15; |
| EnumU32_2 b : 15; |
| }; |
| static_assert(sizeof(F) == 4); |
| |
| struct G { |
| EnumU32_1 a : 15; |
| EnumU64 b : 15; |
| // expected-warning@-1 {{bit-field 'b' of type 'EnumU64' has a different storage size than the preceding bit-field (8 vs 4 bytes) and will not be packed under the Microsoft ABI}} |
| // expected-note@-3 {{preceding bit-field 'a' declared here with type 'EnumU32_1'}} |
| }; |
| |
| #ifdef MS_BITFIELDS |
| static_assert(sizeof(G) == 16); |
| #else |
| static_assert(sizeof(G) == 8); |
| #endif |
| |
| struct H { |
| EnumU32_1 a : 10; |
| EnumI32 b : 10; |
| EnumU32_1 c : 10; |
| }; |
| static_assert(sizeof(H) == 4); |
| |
| struct I { |
| EnumU8 a : 3; |
| EnumI8 b : 5; |
| EnumU32_1 c : 10; |
| // expected-warning@-1 {{bit-field 'c' of type 'EnumU32_1' has a different storage size than the preceding bit-field (4 vs 1 bytes) and will not be packed under the Microsoft ABI}} |
| // expected-note@-3 {{preceding bit-field 'b' declared here with type 'EnumI8'}} |
| }; |
| #ifdef MS_BITFIELDS |
| static_assert(sizeof(I) == 8); |
| #else |
| static_assert(sizeof(I) == 4); |
| #endif |
| |
| struct J { |
| EnumU8 : 0; |
| EnumU8 b : 4; |
| }; |
| static_assert(sizeof(J) == 1); |
| |
| struct K { |
| EnumU8 a : 4; |
| EnumU8 : 0; |
| }; |
| static_assert(sizeof(K) == 1); |
| |
| struct L { |
| EnumU32_1 a : 10; |
| EnumU32_2 b : 10; |
| EnumU32_1 c : 10; |
| }; |
| |
| static_assert(sizeof(L) == 4); |
| |
| struct M { |
| EnumU32_1 a : 10; |
| EnumI32 b : 10; |
| EnumU32_1 c : 10; |
| }; |
| |
| static_assert(sizeof(M) == 4); |
| |
| struct N { |
| EnumU32_1 a : 10; |
| EnumU64 b : 10; |
| // expected-warning@-1 {{bit-field 'b' of type 'EnumU64' has a different storage size than the preceding bit-field (8 vs 4 bytes) and will not be packed under the Microsoft ABI}} |
| // expected-note@-3 {{preceding bit-field 'a' declared here with type 'EnumU32_1'}} |
| EnumU32_1 c : 10; |
| // expected-warning@-1 {{bit-field 'c' of type 'EnumU32_1' has a different storage size than the preceding bit-field (4 vs 8 bytes) and will not be packed under the Microsoft ABI}} |
| // expected-note@-5 {{preceding bit-field 'b' declared here with type 'EnumU64'}} |
| }; |
| |
| #ifdef MS_BITFIELDS |
| static_assert(sizeof(N) == 24); |
| #else |
| static_assert(sizeof(N) == 8); |
| #endif |
| |
| struct O { |
| EnumU16 a : 10; |
| EnumU32_1 b : 10; |
| // expected-warning@-1 {{bit-field 'b' of type 'EnumU32_1' has a different storage size than the preceding bit-field (4 vs 2 bytes) and will not be packed under the Microsoft ABI}} |
| // expected-note@-3 {{preceding bit-field 'a' declared here with type 'EnumU16'}} |
| }; |
| #ifdef MS_BITFIELDS |
| static_assert(sizeof(O) == 8); |
| #else |
| static_assert(sizeof(O) == 4); |
| #endif |
| |
| struct P { |
| EnumU32_1 a : 10; |
| EnumU16 b : 10; |
| // expected-warning@-1 {{bit-field 'b' of type 'EnumU16' has a different storage size than the preceding bit-field (2 vs 4 bytes) and will not be packed under the Microsoft ABI}} |
| // expected-note@-3 {{preceding bit-field 'a' declared here with type 'EnumU32_1'}} |
| }; |
| #ifdef MS_BITFIELDS |
| static_assert(sizeof(P) == 8); |
| #else |
| static_assert(sizeof(P) == 4); |
| #endif |
| |
| struct Q { |
| EnumU8 a : 6; |
| EnumU16 b : 6; |
| // expected-warning@-1 {{bit-field 'b' of type 'EnumU16' has a different storage size than the preceding bit-field (2 vs 1 bytes) and will not be packed under the Microsoft ABI}} |
| // expected-note@-3 {{preceding bit-field 'a' declared here with type 'EnumU8'}} |
| }; |
| #ifdef MS_BITFIELDS |
| static_assert(sizeof(Q) == 4); |
| #else |
| static_assert(sizeof(Q) == 2); |
| #endif |
| |
| struct R { |
| EnumU16 a : 9; |
| EnumU16 b : 9; |
| EnumU8 c : 6; |
| // expected-warning@-1 {{bit-field 'c' of type 'EnumU8' has a different storage size than the preceding bit-field (1 vs 2 bytes) and will not be packed under the Microsoft ABI}} |
| // expected-note@-3 {{preceding bit-field 'b' declared here with type 'EnumU16'}} |
| }; |
| |
| #ifdef MS_BITFIELDS |
| static_assert(sizeof(R) == 6); |
| #else |
| static_assert(sizeof(R) == 4); |
| #endif |
| |
| struct S { |
| char a : 4; |
| char b : 4; |
| char c : 4; |
| char d : 4; |
| short x : 7; |
| // expected-warning@-1 {{bit-field 'x' of type 'short' has a different storage size than the preceding bit-field (2 vs 1 bytes) and will not be packed under the Microsoft ABI}} |
| // expected-note@-3 {{preceding bit-field 'd' declared here with type 'char'}} |
| // This is a false positive. Reporting this correctly requires duplicating the record layout process |
| // in target and MS layout modes, and it's also unclear if that's the correct choice for users of |
| // this diagnostic. |
| short y : 9; |
| }; |
| |
| static_assert(sizeof(S) == 4); |