diff --git a/src/Changes b/src/Changes index 0b18da167f..44d070f7bf 100644 --- a/src/Changes +++ b/src/Changes @@ -1,5 +1,46 @@ Version 7.1 +10/16/26 [GH #327] +__has_unique_object_representations fixes + +A base class that declares no nonstatic data members of its own but inherits +some (and is therefore not empty) was treated as an empty base class. Its +size was then counted as tail padding, so the trait was incorrectly FALSE for +classes derived from it. For example, with --c++11: + + struct A { char i; }; + struct B : A {}; + struct C : B {}; + static_assert(__has_unique_object_representations(C), ""); // Previously + // failed. + +This is now fixed. In addition: + + - An unnamed bit-field of nonzero width is now treated as padding (making + the result FALSE), as the standard requires. For example: + + struct S { char a; char : 8; char b; }; + // __has_unique_object_representations(S) is now FALSE. + + The previous behavior (TRUE) is retained in g++ modes before 13.1 + (except 10.5, 11.4, and 12.3) and in Clang modes before 17. + + - In a union, an unnamed bit-field overlaps the other members, so the + rule above does not apply; as before, a bit-field narrower than the + union is treated as padding, except in Clang modes. Microsoft mode now + also does not treat it as padding, matching MSVC. For example: + + union U { int x : 3; }; + // __has_unique_object_representations(U) is now TRUE with + // --microsoft. + + - Volatile-qualified non-class types (e.g., "volatile int") are treated as + not having unique object representations only in g++ modes before + version 10 (previously this was done for all g++ versions, including + Clang modes). In other modes the result is the same as for the + unqualified type, as the standard requires. + + 10/15/26 [GH #309] Position of (lowered) cleanups at the end of a function body diff --git a/src/folding.c b/src/folding.c index 221d60bf1f..4bf480dd39 100644 --- a/src/folding.c +++ b/src/folding.c @@ -8939,6 +8939,27 @@ with cssp are trivial. } /* all_copy_constructors_trivial */ +static a_boolean unnamed_bit_field_is_padding(void) +/* +Return TRUE if an unnamed bit-field of non-zero width is considered padding +by type_has_unique_object_representations. That is the standard behavior; +it is not done by Clang before version 17 or by g++ before 13.1 (except for +the backports to g++ 10.5, 11.4, and 12.3). +*/ +{ + a_boolean result = TRUE; + + if (clang_mode) { + result = clang_version >= 170000; + } else if (gpp_mode) { + result = gnu_version >= 120300 || + (gnu_version >= 110400 && gnu_version < 120000) || + (gnu_version >= 100500 && gnu_version < 110000); + } /* if */ + return result; +} /* unnamed_bit_field_is_padding */ + + static a_boolean type_has_unique_object_representations( a_type_ptr type, a_targ_size_t *after_base_members, @@ -8999,8 +9020,7 @@ architectures for which these assumptions are not valid. if (bcp->offset != end_of_last_subobject) { /* There's padding between base class subobjects. */ result = FALSE; - } else if (bcp->type->variant.class_struct_union.field_list == - NULL) { + } else if (is_empty_class_type(bcp->type)) { /* An empty base class: treat it as having size 0 and do not check type_has_unique_object_representation, since an empty class will consist of nothing but padding. If it was not @@ -9029,11 +9049,20 @@ architectures for which these assumptions are not valid. a_type_ptr field_type = skip_typerefs(field->type); if (type->kind == (a_type_kind)tk_union && ((prev_field != NULL && field_type->size != prev_field_size) || - (field->is_bit_field && !clang_mode && + (field->is_bit_field && !clang_mode && !microsoft_mode && field->bit_size < type->size * targ_char_bit))) { /* There will be padding in a union if not all fields are the - same size or (for g++, not clang) if a bit-field is shorter - than the size of the union. */ + same size or (except for Clang and Microsoft) if a bit-field + is shorter than the size of the union. */ + result = FALSE; + } else if (type->kind != tk_union && + field->is_bit_field && field->bit_size != 0 && + unnamed_bit_field_is_padding() && + field->source_corresp.assoc_info == + (char*)get_unnamed_field_symbol()) { + /* An unnamed bit-field of non-zero width is padding. (In a + union, an unnamed bit-field overlaps the other members, so + it is handled by the size test above instead.) */ result = FALSE; } else if (field->offset != end_of_last_subobject || field->offset_bit_remainder != bit_offset_of_end) { @@ -9078,9 +9107,10 @@ architectures for which these assumptions are not valid. } /* if */ } /* if */ } /* if */ - } else if (gpp_mode && is_volatile_qualified_type(orig_type)) { - /* g++ treats volatile-qualified types as not having unique object - representations. */ + } else if (gpp_version_is(< 100000) && + is_volatile_qualified_type(orig_type)) { + /* g++ before version 10 treats volatile-qualified non-class types as + not having unique object representations. */ result = FALSE; } else { /* A non-class type. */ diff --git a/tests/expectations/edg_x86_64/imported.log b/tests/expectations/edg_x86_64/imported.log index 12f913d087..c18eaad9ab 100644 --- a/tests/expectations/edg_x86_64/imported.log +++ b/tests/expectations/edg_x86_64/imported.log @@ -6872,7 +6872,6 @@ gnu/cpp/cpp1z/fold1/test.mft.cpp:fn:-DTEST_NUMBER=1 --c++17:FAIL: gnu/cpp/cpp1z/fold5.sft.cpp:fn:-DTEST_NUMBER=1 --c++11:FAIL: gnu/cpp/cpp1z/fold6.sft.cpp:fn:-DTEST_NUMBER=1 --c++17:FAIL: gnu/cpp/cpp1z/has-unique-obj-representations1.sft.cpp:fp:-DTEST_NUMBER=1 --c++11:FAIL: -gnu/cpp/cpp1z/has-unique-obj-representations3.sft.cpp:fp:-DTEST_NUMBER=1 --c++11:FAIL: gnu/cpp/cpp1z/inh-ctor1.sft.cpp:fn:-DTEST_NUMBER=1 --c++11:FAIL: gnu/cpp/cpp1z/inh-ctor33.sft.cpp:lp:-DTEST_NUMBER=1 --c++11:FAIL: gnu/cpp/cpp1z/inh-ctor38.sft.cpp:rp:-DTEST_NUMBER=1 --c++11:FAIL: diff --git a/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/default.1.1.txt b/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/default.1.1.txt index eb26fc2c03..ec879ba032 100644 --- a/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/default.1.1.txt +++ b/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/default.1.1.txt @@ -375,38 +375,6 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers static_assert(!__is_trivially_destructible(AnIncompleteType[1])); // expected-error {{incomplete type}} ^ -"Test_name.c", line 3482: error: static assertion failed with "integrals are" - static_assert(__has_unique_object_representations(volatile int), "integrals are"); - ^ - -"Test_name.c", line 3483: error: static assertion failed with "integrals are" - static_assert(__has_unique_object_representations(const volatile int), "integrals are"); - ^ - -"Test_name.c", line 3502: error: static assertion failed with "even function pointers" - static_assert(__has_unique_object_representations(volatile FP), "even function pointers"); - ^ - -"Test_name.c", line 3503: error: static assertion failed with "even function pointers" - static_assert(__has_unique_object_representations(const volatile FP), "even function pointers"); - ^ - -"Test_name.c", line 3507: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(volatile PMF), "and pointer to members"); - ^ - -"Test_name.c", line 3508: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(const volatile PMF), "and pointer to members"); - ^ - -"Test_name.c", line 3512: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(volatile PMD), "and pointer to members"); - ^ - -"Test_name.c", line 3513: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(const volatile PMD), "and pointer to members"); - ^ - "Test_name.c", line 3544: error: an incomplete class type is not allowed static_assert(!__has_unique_object_representations(AnIncompleteType)); ^ @@ -431,14 +399,6 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers char d : 1; ^ -"Test_name.c", line 3777: error: static assertion failed with "Bitfield padding" - static_assert(!__has_unique_object_representations(UnnamedBitfield), "Bitfield padding"); - ^ - -"Test_name.c", line 3778: error: static assertion failed with "Bitfield padding" - static_assert(!__has_unique_object_representations(UnnamedBitfieldPacked), "Bitfield padding"); - ^ - "Test_name.c", line 3790: warning: declared size for bit field is larger than the size of the bit field type; truncated to 8 bits bool b : 16; ^ @@ -695,5 +655,5 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers #error Programming model currently unsupported; please add a new entry. ^ -124 errors and 1 catastrophic error detected in the compilation of "Test_name.c". +114 errors and 1 catastrophic error detected in the compilation of "Test_name.c". Compilation terminated. diff --git a/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_32.1.1.txt b/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_32.1.1.txt index aceebd43b6..01377d3b3d 100644 --- a/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_32.1.1.txt +++ b/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_32.1.1.txt @@ -379,38 +379,6 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers static_assert(!__is_trivially_destructible(AnIncompleteType[1])); // expected-error {{incomplete type}} ^ -"Test_name.c", line 3482: error: static assertion failed with "integrals are" - static_assert(__has_unique_object_representations(volatile int), "integrals are"); - ^ - -"Test_name.c", line 3483: error: static assertion failed with "integrals are" - static_assert(__has_unique_object_representations(const volatile int), "integrals are"); - ^ - -"Test_name.c", line 3502: error: static assertion failed with "even function pointers" - static_assert(__has_unique_object_representations(volatile FP), "even function pointers"); - ^ - -"Test_name.c", line 3503: error: static assertion failed with "even function pointers" - static_assert(__has_unique_object_representations(const volatile FP), "even function pointers"); - ^ - -"Test_name.c", line 3507: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(volatile PMF), "and pointer to members"); - ^ - -"Test_name.c", line 3508: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(const volatile PMF), "and pointer to members"); - ^ - -"Test_name.c", line 3512: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(volatile PMD), "and pointer to members"); - ^ - -"Test_name.c", line 3513: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(const volatile PMD), "and pointer to members"); - ^ - "Test_name.c", line 3544: error: an incomplete class type is not allowed static_assert(!__has_unique_object_representations(AnIncompleteType)); ^ @@ -435,14 +403,6 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers char d : 1; ^ -"Test_name.c", line 3777: error: static assertion failed with "Bitfield padding" - static_assert(!__has_unique_object_representations(UnnamedBitfield), "Bitfield padding"); - ^ - -"Test_name.c", line 3778: error: static assertion failed with "Bitfield padding" - static_assert(!__has_unique_object_representations(UnnamedBitfieldPacked), "Bitfield padding"); - ^ - "Test_name.c", line 3790: warning: declared size for bit field is larger than the size of the bit field type; truncated to 8 bits bool b : 16; ^ @@ -695,5 +655,5 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers #error Programming model currently unsupported; please add a new entry. ^ -124 errors and 1 catastrophic error detected in the compilation of "Test_name.c". +114 errors and 1 catastrophic error detected in the compilation of "Test_name.c". Compilation terminated. diff --git a/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_32_cp.1.1.txt b/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_32_cp.1.1.txt index cb066ca2d7..9142873062 100644 --- a/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_32_cp.1.1.txt +++ b/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_32_cp.1.1.txt @@ -363,38 +363,6 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers static_assert(!__is_trivially_destructible(AnIncompleteType[1])); // expected-error {{incomplete type}} ^ -"Test_name.c", line 3482: error: static assertion failed with "integrals are" - static_assert(__has_unique_object_representations(volatile int), "integrals are"); - ^ - -"Test_name.c", line 3483: error: static assertion failed with "integrals are" - static_assert(__has_unique_object_representations(const volatile int), "integrals are"); - ^ - -"Test_name.c", line 3502: error: static assertion failed with "even function pointers" - static_assert(__has_unique_object_representations(volatile FP), "even function pointers"); - ^ - -"Test_name.c", line 3503: error: static assertion failed with "even function pointers" - static_assert(__has_unique_object_representations(const volatile FP), "even function pointers"); - ^ - -"Test_name.c", line 3507: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(volatile PMF), "and pointer to members"); - ^ - -"Test_name.c", line 3508: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(const volatile PMF), "and pointer to members"); - ^ - -"Test_name.c", line 3512: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(volatile PMD), "and pointer to members"); - ^ - -"Test_name.c", line 3513: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(const volatile PMD), "and pointer to members"); - ^ - "Test_name.c", line 3544: error: an incomplete class type is not allowed static_assert(!__has_unique_object_representations(AnIncompleteType)); ^ @@ -419,14 +387,6 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers char d : 1; ^ -"Test_name.c", line 3777: error: static assertion failed with "Bitfield padding" - static_assert(!__has_unique_object_representations(UnnamedBitfield), "Bitfield padding"); - ^ - -"Test_name.c", line 3778: error: static assertion failed with "Bitfield padding" - static_assert(!__has_unique_object_representations(UnnamedBitfieldPacked), "Bitfield padding"); - ^ - "Test_name.c", line 3790: warning: declared size for bit field is larger than the size of the bit field type; truncated to 8 bits bool b : 16; ^ @@ -635,5 +595,5 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers #error Programming model currently unsupported; please add a new entry. ^ -124 errors and 1 catastrophic error detected in the compilation of "Test_name.c". +114 errors and 1 catastrophic error detected in the compilation of "Test_name.c". Compilation terminated. diff --git a/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_64_cp.1.1.txt b/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_64_cp.1.1.txt index d4391885f2..5d28e8863c 100644 --- a/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_64_cp.1.1.txt +++ b/tests/tests/imported/clang/cpp/SemaCXX/.type-traits.rto/edg_x86_64_cp.1.1.txt @@ -359,38 +359,6 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers static_assert(!__is_trivially_destructible(AnIncompleteType[1])); // expected-error {{incomplete type}} ^ -"Test_name.c", line 3482: error: static assertion failed with "integrals are" - static_assert(__has_unique_object_representations(volatile int), "integrals are"); - ^ - -"Test_name.c", line 3483: error: static assertion failed with "integrals are" - static_assert(__has_unique_object_representations(const volatile int), "integrals are"); - ^ - -"Test_name.c", line 3502: error: static assertion failed with "even function pointers" - static_assert(__has_unique_object_representations(volatile FP), "even function pointers"); - ^ - -"Test_name.c", line 3503: error: static assertion failed with "even function pointers" - static_assert(__has_unique_object_representations(const volatile FP), "even function pointers"); - ^ - -"Test_name.c", line 3507: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(volatile PMF), "and pointer to members"); - ^ - -"Test_name.c", line 3508: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(const volatile PMF), "and pointer to members"); - ^ - -"Test_name.c", line 3512: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(volatile PMD), "and pointer to members"); - ^ - -"Test_name.c", line 3513: error: static assertion failed with "and pointer to members" - static_assert(__has_unique_object_representations(const volatile PMD), "and pointer to members"); - ^ - "Test_name.c", line 3544: error: an incomplete class type is not allowed static_assert(!__has_unique_object_representations(AnIncompleteType)); ^ @@ -415,14 +383,6 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers char d : 1; ^ -"Test_name.c", line 3777: error: static assertion failed with "Bitfield padding" - static_assert(!__has_unique_object_representations(UnnamedBitfield), "Bitfield padding"); - ^ - -"Test_name.c", line 3778: error: static assertion failed with "Bitfield padding" - static_assert(!__has_unique_object_representations(UnnamedBitfieldPacked), "Bitfield padding"); - ^ - "Test_name.c", line 3790: warning: declared size for bit field is larger than the size of the bit field type; truncated to 8 bits bool b : 16; ^ @@ -635,5 +595,5 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers #error Programming model currently unsupported; please add a new entry. ^ -124 errors and 1 catastrophic error detected in the compilation of "Test_name.c". +114 errors and 1 catastrophic error detected in the compilation of "Test_name.c". Compilation terminated. diff --git a/tests/tests/imported/gnu/cpp/cpp1z/.has-unique-obj-representations3.rto/default.1.1.txt b/tests/tests/imported/gnu/cpp/cpp1z/.has-unique-obj-representations3.rto/default.1.1.txt index dedd201510..dcdf4c999a 100644 --- a/tests/tests/imported/gnu/cpp/cpp1z/.has-unique-obj-representations3.rto/default.1.1.txt +++ b/tests/tests/imported/gnu/cpp/cpp1z/.has-unique-obj-representations3.rto/default.1.1.txt @@ -1,16 +1 @@ fe_only -DTEST_NUMBER=1 --gnu_version=999999 -tused -e 200 --no_wrap --no_wrap_diagnostics --c++11 Test_name.c -"Test_name.c", line 10: error: static assertion failed with "" - static_assert (__has_unique_object_representations (U) == false, ""); - ^ -"Test_name.c", line 10: note: the final comparison was 1 == 0 - static_assert (__has_unique_object_representations (U) == false, ""); - ^ - -"Test_name.c", line 11: error: static assertion failed with "" - static_assert (__has_unique_object_representations (V) == false, ""); - ^ -"Test_name.c", line 11: note: the final comparison was 1 == 0 - static_assert (__has_unique_object_representations (V) == false, ""); - ^ - -2 errors detected in the compilation of "Test_name.c". diff --git a/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.1.1.txt b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.1.1.txt new file mode 100644 index 0000000000..dbd2e6e9fb --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.1.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=1 --c++11 -DSTD_MODE Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.10.1.txt b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.10.1.txt new file mode 100644 index 0000000000..f81365ba08 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.10.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=10 --c++11 --microsoft Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.2.1.txt b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.2.1.txt new file mode 100644 index 0000000000..14683cdbda --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.2.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=2 --c++11 --g++ --gnu_version=90400 -DOLD_PAD Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.3.1.txt b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.3.1.txt new file mode 100644 index 0000000000..02a47a91fd --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.3.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=3 --c++11 --g++ --gnu_version=100400 -DOLD_PAD Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.4.1.txt b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.4.1.txt new file mode 100644 index 0000000000..54bbbbc35c --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.4.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=4 --c++11 --g++ --gnu_version=100500 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.5.1.txt b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.5.1.txt new file mode 100644 index 0000000000..80432f98ac --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.5.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=5 --c++11 --g++ --gnu_version=120200 -DOLD_PAD Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.6.1.txt b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.6.1.txt new file mode 100644 index 0000000000..d6cfc5db1e --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.6.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=6 --c++11 --g++ --gnu_version=120300 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.7.1.txt b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.7.1.txt new file mode 100644 index 0000000000..de5edc295a --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.7.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=7 --c++11 --g++ --gnu_version=150100 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.8.1.txt b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.8.1.txt new file mode 100644 index 0000000000..dc5e2f0c38 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.8.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=8 --c++11 --clang --clang_version=160000 -DOLD_PAD Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.9.1.txt b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.9.1.txt new file mode 100644 index 0000000000..9d3be5664f --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-bit-field.rto/default.9.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=9 --c++11 --clang --clang_version=170000 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.1.1.txt b/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.1.1.txt new file mode 100644 index 0000000000..4018012f7d --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.1.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=1 --c++17 --g++ --gnu_version=150100 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.2.1.txt b/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.2.1.txt new file mode 100644 index 0000000000..a2d2107875 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.2.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=2 --c++17 --clang --clang_version=190000 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.3.1.txt b/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.3.1.txt new file mode 100644 index 0000000000..7b2ce29244 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.3.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=3 --c++17 -DSTD_MODE Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.4.1.txt b/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.4.1.txt new file mode 100644 index 0000000000..09c0269a52 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-inherited-base.rto/default.4.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=4 --c++17 --microsoft Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.1.1.txt b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.1.1.txt new file mode 100644 index 0000000000..dbd2e6e9fb --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.1.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=1 --c++11 -DSTD_MODE Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.2.1.txt b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.2.1.txt new file mode 100644 index 0000000000..cb11de8965 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.2.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=2 --c++11 --g++ --gnu_version=90400 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.3.1.txt b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.3.1.txt new file mode 100644 index 0000000000..7ff502308c --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.3.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=3 --c++11 --g++ --gnu_version=150100 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.4.1.txt b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.4.1.txt new file mode 100644 index 0000000000..d51608c0fc --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.4.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=4 --c++11 --clang --clang_version=160000 -DCLANG Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.5.1.txt b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.5.1.txt new file mode 100644 index 0000000000..4de569fbf1 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.5.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=5 --c++11 --clang --clang_version=190000 -DCLANG Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.6.1.txt b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.6.1.txt new file mode 100644 index 0000000000..36e125d4d0 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-union-bit-field.rto/default.6.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=6 --c++11 --microsoft -DCLANG Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.1.1.txt b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.1.1.txt new file mode 100644 index 0000000000..dbd2e6e9fb --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.1.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=1 --c++11 -DSTD_MODE Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.2.1.txt b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.2.1.txt new file mode 100644 index 0000000000..edd040e5db --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.2.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=2 --c++11 --g++ --gnu_version=90400 -DOLD_GNU Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.3.1.txt b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.3.1.txt new file mode 100644 index 0000000000..f22c509a0d --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.3.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=3 --c++11 --g++ --gnu_version=100100 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.4.1.txt b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.4.1.txt new file mode 100644 index 0000000000..1e493b5953 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.4.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=4 --c++11 --g++ --gnu_version=150100 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.5.1.txt b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.5.1.txt new file mode 100644 index 0000000000..6df43e0219 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.5.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=5 --c++11 --clang --clang_version=160000 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.6.1.txt b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.6.1.txt new file mode 100644 index 0000000000..bf794a10d9 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.6.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=6 --c++11 --clang --clang_version=190000 Test_name.c diff --git a/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.7.1.txt b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.7.1.txt new file mode 100644 index 0000000000..905038b342 --- /dev/null +++ b/tests/tests/regressions/.has-unique-object-rep-volatile.rto/default.7.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=7 --c++11 --microsoft Test_name.c diff --git a/tests/tests/regressions/has-unique-object-rep-bit-field.sft.cpp b/tests/tests/regressions/has-unique-object-rep-bit-field.sft.cpp new file mode 100644 index 0000000000..a597ac9f00 --- /dev/null +++ b/tests/tests/regressions/has-unique-object-rep-bit-field.sft.cpp @@ -0,0 +1,25 @@ +//remark:has_unique_object_representations with unnamed bit-fields +//type:fp +//options_all:--c++11 +//options:-DSTD_MODE:--g++ --gnu_version=90400 -DOLD_PAD:--g++ --gnu_version=100400 -DOLD_PAD:--g++ --gnu_version=100500:--g++ --gnu_version=120200 -DOLD_PAD:--g++ --gnu_version=120300:--g++ --gnu_version=150100:--clang --clang_version=160000 -DOLD_PAD:--clang --clang_version=170000:--microsoft + +// Standard behavior: an unnamed bit-field of nonzero width is padding. +// Older g++ and Clang versions did not treat it as padding. +struct S { char a; char : 8; char b; }; +struct T { char a; char b; char : 8; }; // Unnamed bit-field at the end. +struct U : S {}; // Via a base class. +struct V { S s; }; // Via a member. +struct N { char a; char x : 8; char b; }; // Named: not padding. + +#ifdef OLD_PAD +static_assert(__has_unique_object_representations(S), "S"); +static_assert(__has_unique_object_representations(T), "T"); +static_assert(__has_unique_object_representations(U), "U"); +static_assert(__has_unique_object_representations(V), "V"); +#else +static_assert(!__has_unique_object_representations(S), "S"); +static_assert(!__has_unique_object_representations(T), "T"); +static_assert(!__has_unique_object_representations(U), "U"); +static_assert(!__has_unique_object_representations(V), "V"); +#endif +static_assert(__has_unique_object_representations(N), "N"); diff --git a/tests/tests/regressions/has-unique-object-rep-inherited-base.sft.cpp b/tests/tests/regressions/has-unique-object-rep-inherited-base.sft.cpp new file mode 100644 index 0000000000..98da0e3e77 --- /dev/null +++ b/tests/tests/regressions/has-unique-object-rep-inherited-base.sft.cpp @@ -0,0 +1,24 @@ +//remark:has_unique_object_representations with a base that has no direct fields +//type:fp +//options_all:--c++17 +//options:--g++ --gnu_version=150100:--clang --clang_version=190000:-DSTD_MODE:--microsoft + +// B declares no fields but is not empty (it inherits A::i), so it must not +// be skipped as an empty base when checking C. +struct A { char i; }; +struct B : A {}; +struct C : B {}; +struct D : C {}; +struct E {}; +struct F : E, B {}; // Real empty base is still skipped. +struct G : B { char j; }; +struct P { int i; char c; }; // Tail padding. +struct Q : P {}; + +static_assert(__has_unique_object_representations(B), "B"); +static_assert(__has_unique_object_representations(C), "C"); +static_assert(__has_unique_object_representations(D), "D"); +static_assert(__has_unique_object_representations(F), "F"); +static_assert(__has_unique_object_representations(G), "G"); +static_assert(!__has_unique_object_representations(P), "P"); +static_assert(!__has_unique_object_representations(Q), "Q"); diff --git a/tests/tests/regressions/has-unique-object-rep-union-bit-field.sft.cpp b/tests/tests/regressions/has-unique-object-rep-union-bit-field.sft.cpp new file mode 100644 index 0000000000..fa2c52c93a --- /dev/null +++ b/tests/tests/regressions/has-unique-object-rep-union-bit-field.sft.cpp @@ -0,0 +1,27 @@ +//remark:has_unique_object_representations with bit-fields in unions +//type:fp +//options_all:--c++11 +//options:-DSTD_MODE:--g++ --gnu_version=90400:--g++ --gnu_version=150100:--clang --clang_version=160000 -DCLANG:--clang --clang_version=190000 -DCLANG:--microsoft -DCLANG + +// An unnamed bit-field in a union overlaps the other members; it must not be +// treated as padding by itself. A bit-field shorter than the union is +// padding except in Clang and Microsoft modes (they ignore that case). +union U1 { int x : 3; int y; }; // Short named bit-field. +union U2 { int x : 32; }; // Full-width named bit-field. +union U3 { int x; int : 32; }; // Full-width unnamed bit-field. +union U4 { int x; int : 8; }; // Short unnamed bit-field. +union U5 { int x : 3; }; // Only a short bit-field. +struct S6 { union { int x; int : 32; } u; }; + +#ifdef CLANG +static_assert(__has_unique_object_representations(U1), "U1"); +static_assert(__has_unique_object_representations(U4), "U4"); +static_assert(__has_unique_object_representations(U5), "U5"); +#else +static_assert(!__has_unique_object_representations(U1), "U1"); +static_assert(!__has_unique_object_representations(U4), "U4"); +static_assert(!__has_unique_object_representations(U5), "U5"); +#endif +static_assert(__has_unique_object_representations(U2), "U2"); +static_assert(__has_unique_object_representations(U3), "U3"); +static_assert(__has_unique_object_representations(S6), "S6"); diff --git a/tests/tests/regressions/has-unique-object-rep-volatile.sft.cpp b/tests/tests/regressions/has-unique-object-rep-volatile.sft.cpp new file mode 100644 index 0000000000..727ed59022 --- /dev/null +++ b/tests/tests/regressions/has-unique-object-rep-volatile.sft.cpp @@ -0,0 +1,19 @@ +//remark:has_unique_object_representations with volatile-qualified types +//type:fp +//options_all:--c++11 +//options:-DSTD_MODE:--g++ --gnu_version=90400 -DOLD_GNU:--g++ --gnu_version=100100:--g++ --gnu_version=150100:--clang --clang_version=160000:--clang --clang_version=190000:--microsoft + +// Standard behavior: cv-qualification does not affect the result. g++ +// before version 10 treated volatile-qualified non-class types as not having +// unique object representations. +#ifdef OLD_GNU +static_assert(!__has_unique_object_representations(volatile int), "vi"); +static_assert(!__has_unique_object_representations(const volatile int), + "cvi"); +#else +static_assert(__has_unique_object_representations(volatile int), "vi"); +static_assert(__has_unique_object_representations(const volatile int), + "cvi"); +#endif +static_assert(__has_unique_object_representations(int), "i"); +static_assert(__has_unique_object_representations(const int), "ci");