diff options
author | Martin Uecker <uecker@tugraz.at> | 2023-08-15 22:38:14 +0200 |
---|---|---|
committer | Martin Uecker <uecker@tugraz.at> | 2023-12-21 08:43:16 +0100 |
commit | 140aa2cdf93c7729e362b09534535395357183f0 (patch) | |
tree | d64e26001033f9e6079a5720a8da4746090e4a5e /gcc/c/c-tree.h | |
parent | ced651b7757e6ef7e7e309f022cd71b4b6ead295 (diff) | |
download | gcc-140aa2cdf93c7729e362b09534535395357183f0.zip gcc-140aa2cdf93c7729e362b09534535395357183f0.tar.gz gcc-140aa2cdf93c7729e362b09534535395357183f0.tar.bz2 |
c23: aliasing of compatible tagged types
Tell the backend which types are equivalent by setting
TYPE_CANONICAL to one struct in the set of equivalent
structs. Structs are considered equivalent by ignoring
all sizes of arrays nested in types below field level.
The following two structs are incompatible and lvalues
with these types can be assumed not to alias:
struct foo { int a[3]; };
struct foo { int a[4]; };
The following two structs are also incompatible, but
will get the same TYPE_CANONICAL and it is then not
exploited that lvalues with those types can not alias:
struct bar { int (*p)[3]; };
struct bar { int (*p)[4]; };
The reason is that both are compatible to
struct bar { int (*p)[]; };
and therefore are in the same equivalence class. For
the same reason all enums with the same underyling type
are in the same equivalence class. Tests are added
for the expected aliasing behavior with optimization.
gcc/c:
* c-decl.cc (c_struct_hasher): Hash stable for struct
types.
(c_struct_hasher::hash, c_struct_hasher::equal): New
functions.
(finish_struct): Set TYPE_CANONICAL to first struct in
equivalence class.
* c-objc-common.cc (c_get_alias_set): Let structs or
unions with variable size alias anything.
* c-tree.h (comptypes_equiv): New prototype.
* c-typeck.cc (comptypes_equiv): New function.
(comptypes_internal): Implement equivalence mode.
(tagged_types_tu_compatible): Implement equivalence mode.
gcc/testsuite:
* gcc.dg/c23-tag-2.c: Activate.
* gcc.dg/c23-tag-5.c: Activate.
* gcc.dg/c23-tag-alias-1.c: New test.
* gcc.dg/c23-tag-alias-2.c: New test.
* gcc.dg/c23-tag-alias-3.c: New test.
* gcc.dg/c23-tag-alias-4.c: New test.
* gcc.dg/c23-tag-alias-5.c: New test.
* gcc.dg/gnu23-tag-alias-1.c: New test.
* gcc.dg/gnu23-tag-alias-2.c: New test.
* gcc.dg/gnu23-tag-alias-3.c: New test.
* gcc.dg/gnu23-tag-alias-4.c: New test.
* gcc.dg/gnu23-tag-alias-5.c: New test.
* gcc.dg/gnu23-tag-alias-6.c: New test.
* gcc.dg/gnu23-tag-alias-7.c: New test.
Diffstat (limited to 'gcc/c/c-tree.h')
-rw-r--r-- | gcc/c/c-tree.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 54f1353..02a09e5 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -759,6 +759,7 @@ extern tree require_complete_type (location_t, tree); extern bool same_translation_unit_p (const_tree, const_tree); extern int comptypes (tree, tree); extern bool comptypes_same_p (tree, tree); +extern bool comptypes_equiv_p (tree, tree); extern int comptypes_check_different_types (tree, tree, bool *); extern int comptypes_check_enum_int (tree, tree, bool *); extern bool c_mark_addressable (tree, bool = false); |