c: correct type compatibility for bit-fields [PR117828]
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gcc_check--master-arm |
success
|
Test passed
|
Commit Message
Bit-fields need additional checks for type compatiblity.
Bootstrapped and regression tested on x86_64.
c: correct type compatibility for bit-fields [PR117828]
Add missing test for consistency of bit-fields when comparing tagged
types for compatibility.
PR c/117828
gcc/c/ChangeLog:
* c-typeck.c (tagged_types_tu_compatible_p): Add check.
gcc/testsuite/ChangeLog:
* c23-tag-bitfields-1.c: New test.
* pr117828.c: New test.
Comments
On Thu, 28 Nov 2024, Martin Uecker wrote:
> Bit-fields need additional checks for type compatiblity.
>
>
> Bootstrapped and regression tested on x86_64.
>
>
>
> c: correct type compatibility for bit-fields [PR117828]
>
> Add missing test for consistency of bit-fields when comparing tagged
> types for compatibility.
>
> PR c/117828
>
> gcc/c/ChangeLog:
> * c-typeck.c (tagged_types_tu_compatible_p): Add check.
>
> gcc/testsuite/ChangeLog:
> * c23-tag-bitfields-1.c: New test.
> * pr117828.c: New test.
OK (with the file names corrected in the ChangeLog entries, it's
c-typeck.cc, and gcc.dg/ is needed in the test names).
@@ -1909,18 +1909,33 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
gcc_assert (TREE_CODE (s1) == FIELD_DECL);
gcc_assert (TREE_CODE (s2) == FIELD_DECL);
+ tree ft1 = TREE_TYPE (s1);
+ tree ft2 = TREE_TYPE (s2);
+
if (DECL_NAME (s1) != DECL_NAME (s2))
return false;
if (DECL_ALIGN (s1) != DECL_ALIGN (s2))
return false;
+ if (DECL_C_BIT_FIELD (s1) != DECL_C_BIT_FIELD (s2))
+ return false;
+
+ if (DECL_C_BIT_FIELD (s1))
+ {
+ if (!tree_int_cst_equal (DECL_SIZE (s1), DECL_SIZE (s2)))
+ return false;
+
+ ft1 = DECL_BIT_FIELD_TYPE (s1);
+ ft2 = DECL_BIT_FIELD_TYPE (s2);
+ }
+
data->anon_field = !DECL_NAME (s1);
data->pointedto = false;
const struct tagged_tu_seen_cache *cache = data->cache;
data->cache = &entry;
- bool ret = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), data);
+ bool ret = comptypes_internal (ft1, ft2, data);
data->cache = cache;
if (!ret)
return false;
new file mode 100644
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23" } */
+
+struct bar0 { int r : 16; };
+struct bar0 { int r : 16; };
+
+struct bar1 { int r : 16; };
+struct bar1 { int r : 17; }; /* { dg-error "redefinition" } */
+
+extern struct { int r : 14; } a;
+extern struct { int r : 14; } b;
+
+extern struct { int r : 14; } x;
+extern struct { int r : 13; } x; /* { dg-error "conflicting" } */
+
+struct bar2 { int s; int: 0; };
+struct bar2 { int s; int: 15; }; /* { dg-error "redefinition" } */
+
+struct bar3 { int s; int : 0; };
+struct bar3 { int s; }; /* { dg-error "redefinition" } */
+
+struct bar4 { int r : 3; };
+struct bar4 { const int r : 3; }; /* { dg-error "redefinition" } */
+
+struct bar5 { int r : 16; };
+struct bar5 { int r; }; /* { dg-error "redefinition" } */
+
+union ubar { int r : 16; };
+union ubar { int r : 16; };
+
+union ubar1 { int r : 16; };
+union ubar1 { int r : 17; }; /* { dg-error "redefinition" } */
+
+extern union { int r : 14; } c;
+extern union { int r : 14; } d;
+
+extern union { int r : 14; } y;
+extern union { int r : 13; } y; /* { dg-error "conflicting" } */
+
+union ubar2 { int s; int : 0; };
+union ubar2 { int s; int : 15; }; /* { dg-error "redefinition" } */
+
+union ubar3 { int s: 3; int: 0; };
+union ubar3 { int s: 3; }; /* { dg-error "redefinition" } */
+
+union ubar4 { int r : 3; };
+union ubar4 { const int r : 3; }; /* { dg-error "redefinition" } */
+
+union ubar5 { int r : 16; };
+union ubar5 { int r; }; /* { dg-error "redefinition" } */
+
new file mode 100644
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-g" } */
+
+struct {
+ struct {
+ int Reserved : 32;
+ } u;
+} v;
+struct {
+ struct {
+ int Reserved;
+ } u;
+} w;
+
+