Support for constructing composite types for structs and unions
in C23.
gcc/c:
* c-typeck.cc (composite_type_internal): Adapted from
composite_type to support structs and unions.
(composite_type): New wrapper function.
(build_conditional_operator): Return composite type.
* c-decl.cc (finish_struct): Allow NULL for
enclosing_struct_parse_info.
gcc/testsuite:
* gcc.dg/c23-tag-alias-6.c: New test.
* gcc.dg/c23-tag-composite-1.c: New test.
* gcc.dg/c23-tag-composite-2.c: New test.
* gcc.dg/c23-tag-composite-3.c: New test.
* gcc.dg/c23-tag-composite-4.c: New test.
* gcc.dg/c23-tag-composite-5.c: New test.
* gcc.dg/c23-tag-composite-6.c: New test.
* gcc.dg/c23-tag-composite-7.c: New test.
* gcc.dg/c23-tag-composite-8.c: New test.
* gcc.dg/c23-tag-composite-9.c: New test.
* gcc.dg/gnu23-tag-composite-1.c: New test.
* gcc.dg/gnu23-tag-composite-2.c: New test.
* gcc.dg/gnu23-tag-composite-3.c: New test.
* gcc.dg/gnu23-tag-composite-4.c: New test.
---
gcc/c/c-decl.cc | 21 +--
gcc/c/c-typeck.cc| 137 ---
gcc/testsuite/gcc.dg/c23-tag-alias-6.c | 32 +
gcc/testsuite/gcc.dg/c23-tag-composite-1.c | 26
gcc/testsuite/gcc.dg/c23-tag-composite-2.c | 16 +++
gcc/testsuite/gcc.dg/c23-tag-composite-3.c | 50 +++
gcc/testsuite/gcc.dg/c23-tag-composite-4.c | 21 +++
gcc/testsuite/gcc.dg/c23-tag-composite-5.c | 25
gcc/testsuite/gcc.dg/c23-tag-composite-6.c | 18 +++
gcc/testsuite/gcc.dg/c23-tag-composite-7.c | 20 +++
gcc/testsuite/gcc.dg/c23-tag-composite-8.c | 15 ++
gcc/testsuite/gcc.dg/c23-tag-composite-9.c | 19 +++
gcc/testsuite/gcc.dg/gnu23-tag-composite-1.c | 45 ++
gcc/testsuite/gcc.dg/gnu23-tag-composite-2.c | 30
gcc/testsuite/gcc.dg/gnu23-tag-composite-3.c | 24
gcc/testsuite/gcc.dg/gnu23-tag-composite-4.c | 28
16 files changed, 500 insertions(+), 27 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-alias-6.c
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-composite-1.c
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-composite-2.c
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-composite-3.c
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-composite-4.c
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-composite-5.c
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-composite-6.c
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-composite-7.c
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-composite-8.c
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-composite-9.c
create mode 100644 gcc/testsuite/gcc.dg/gnu23-tag-composite-1.c
create mode 100644 gcc/testsuite/gcc.dg/gnu23-tag-composite-2.c
create mode 100644 gcc/testsuite/gcc.dg/gnu23-tag-composite-3.c
create mode 100644 gcc/testsuite/gcc.dg/gnu23-tag-composite-4.c
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 6639ec35e5f..b72738ea04a 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -9674,7 +9674,7 @@ finish_struct (location_t loc, tree t, tree fieldlist,
tree attributes,
}
/* Check for consistency with previous definition. */
- if (flag_isoc23)
+ if (flag_isoc23 && NULL != enclosing_struct_parse_info)
{
tree vistype = previous_tag (t);
if (vistype
@@ -9744,16 +9744,19 @@ finish_struct (location_t loc, tree t, tree fieldlist,
tree attributes,
if (warn_cxx_compat)
warn_cxx_compat_finish_struct (fieldlist, TREE_CODE (t), loc);
- delete struct_parse_info;
+ if (NULL != enclosing_struct_parse_info)
+{
+ delete struct_parse_info;
- struct_parse_info = enclosing_struct_parse_info;
+ struct_parse_info = enclosing_struct_parse_info;
- /* If this struct is defined inside a struct, add it to
- struct_types. */
- if (warn_cxx_compat
- && struct_parse_info != NULL
- && !in_sizeof && !in_typeof && !in_alignof)
-struct_parse_info->struct_types.safe_push (t);
+ /* If this struct is defined inside a struct, add it to
+struct_types. */
+ if (warn_cxx_compat
+ && struct_parse_info != NULL
+ && !in_sizeof && !in_typeof && !in_alignof)
+ struct_parse_info->struct_types.safe_push (t);
+ }
return t;
}
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 4d3079156ba..ac31eba6e46 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -381,8 +381,15 @@ build_functype_attribute_variant (tree ntype, tree otype,
tree attrs)
nonzero; if that isn't so, this may crash. In particular, we
assume that qualifiers match. */
+struct composite_cache {
+ tree t1;
+ tree t2;
+ tree composite;
+ struct composite_cache* next;
+};
+
tree
-composite_type (tree t1, tree t2)
+composite_type_internal (tree t1, tree t2, struct composite_cache* cache)
{
enum tree_code code1;
enum tree_code code2;
@@ -427,7