From: Martin Uecker <uecker@tugraz.at>
To: gcc-patches@gcc.gnu.org
Cc: Joseph Myers <joseph@codesourcery.com>
Subject: [C PATCH 1/6] c: reorganize recursive type checking
Date: Sat, 26 Aug 2023 18:20:57 +0200 [thread overview]
Message-ID: <1df29de95ff41a02ffd218f4cd69f8f93df35321.camel@tugraz.at> (raw)
In-Reply-To: <4b3866a8cc9b48f3be97c004dedbac8e9149da63.camel@tugraz.at>
Reorganize recursive type checking to use a structure to
store information collected during the recursion and
returned to the caller (warning_needed, enum_and_init_p,
different_types_p).
gcc/c:
* c-typeck.cc (struct comptypes_data): Add structure.
(tagged_types_tu_compatible_p,
function_types_compatible_p, type_lists_compatible_p,
comptypes_internal): Add structure to interface, change
return type to bool, and adapt calls.
(comptarget_types): Change return type too bool.
(comptypes, comptypes_check_enum_int,
comptypes_check_different_types): Adapt calls.
---
gcc/c/c-typeck.cc | 266 ++++++++++++++++++++--------------------------
1 file changed, 114 insertions(+), 152 deletions(-)
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index e6ddf37d412..ed1520ed6ba 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -90,12 +90,14 @@ static bool require_constant_elements;
static bool require_constexpr_value;
static tree qualify_type (tree, tree);
-static int tagged_types_tu_compatible_p (const_tree, const_tree, bool *,
- bool *);
-static int comp_target_types (location_t, tree, tree);
-static int function_types_compatible_p (const_tree, const_tree, bool *,
- bool *);
-static int type_lists_compatible_p (const_tree, const_tree, bool *, bool *);
+struct comptypes_data;
+static bool tagged_types_tu_compatible_p (const_tree, const_tree,
+ struct comptypes_data *);
+static bool comp_target_types (location_t, tree, tree);
+static bool function_types_compatible_p (const_tree, const_tree,
+ struct comptypes_data *);
+static bool type_lists_compatible_p (const_tree, const_tree,
+ struct comptypes_data *);
static tree lookup_field (tree, tree);
static int convert_arguments (location_t, vec<location_t>, tree,
vec<tree, va_gc> *, vec<tree, va_gc> *, tree,
@@ -125,7 +127,8 @@ static tree find_init_member (tree, struct obstack *);
static void readonly_warning (tree, enum lvalue_use);
static int lvalue_or_else (location_t, const_tree, enum lvalue_use);
static void record_maybe_used_decl (tree);
-static int comptypes_internal (const_tree, const_tree, bool *, bool *);
+static bool comptypes_internal (const_tree, const_tree,
+ struct comptypes_data *data);
\f
/* Return true if EXP is a null pointer constant, false otherwise. */
@@ -1039,6 +1042,13 @@ common_type (tree t1, tree t2)
return c_common_type (t1, t2);
}
+struct comptypes_data {
+
+ bool enum_and_int_p;
+ bool different_types_p;
+ bool warning_needed;
+};
+
/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
or various other operations. Return 2 if they are compatible
but a warning may be needed if you use them together. */
@@ -1047,12 +1057,13 @@ int
comptypes (tree type1, tree type2)
{
const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
- int val;
- val = comptypes_internal (type1, type2, NULL, NULL);
+ struct comptypes_data data = { };
+ bool ret = comptypes_internal (type1, type2, &data);
+
free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
- return val;
+ return ret ? (data.warning_needed ? 2 : 1) : 0;
}
/* Like comptypes, but if it returns non-zero because enum and int are
@@ -1062,12 +1073,14 @@ int
comptypes_check_enum_int (tree type1, tree type2, bool *enum_and_int_p)
{
const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
- int val;
- val = comptypes_internal (type1, type2, enum_and_int_p, NULL);
+ struct comptypes_data data = { };
+ bool ret = comptypes_internal (type1, type2, &data);
+ *enum_and_int_p = data.enum_and_int_p;
+
free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
- return val;
+ return ret ? (data.warning_needed ? 2 : 1) : 0;
}
/* Like comptypes, but if it returns nonzero for different types, it
@@ -1078,40 +1091,40 @@ comptypes_check_different_types (tree type1, tree type2,
bool *different_types_p)
{
const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
- int val;
- val = comptypes_internal (type1, type2, NULL, different_types_p);
+ struct comptypes_data data = { };
+ bool ret = comptypes_internal (type1, type2, &data);
+ *different_types_p = data.different_types_p;
+
free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
- return val;
+ return ret ? (data.warning_needed ? 2 : 1) : 0;
}
\f
-/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
- or various other operations. Return 2 if they are compatible
- but a warning may be needed if you use them together. If
- ENUM_AND_INT_P is not NULL, and one type is an enum and the other a
- compatible integer type, then this sets *ENUM_AND_INT_P to true;
- *ENUM_AND_INT_P is never set to false. If DIFFERENT_TYPES_P is not
- NULL, and the types are compatible but different enough not to be
+/* Return true if TYPE1 and TYPE2 are compatible types for assignment
+ or various other operations. If they are compatible but a warning may
+ be needed if you use them together, 'warning_needed' in DATA is set.
+ If one type is an enum and the other a compatible integer type, then
+ this sets 'enum_and_int_p' in DATA to true (it is never set to
+ false). If the types are compatible but different enough not to be
permitted in C11 typedef redeclarations, then this sets
- *DIFFERENT_TYPES_P to true; *DIFFERENT_TYPES_P is never set to
+ 'different_types_p' in DATA to true; it is never set to
false, but may or may not be set if the types are incompatible.
This differs from comptypes, in that we don't free the seen
types. */
-static int
-comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
- bool *different_types_p)
+static bool
+comptypes_internal (const_tree type1, const_tree type2,
+ struct comptypes_data *data)
{
const_tree t1 = type1;
const_tree t2 = type2;
- int attrval, val;
/* Suppress errors caused by previously reported errors. */
if (t1 == t2 || !t1 || !t2
|| TREE_CODE (t1) == ERROR_MARK || TREE_CODE (t2) == ERROR_MARK)
- return 1;
+ return true;
/* Enumerated types are compatible with integer types, but this is
not transitive: two enumerated types in the same translation unit
@@ -1124,10 +1137,8 @@ comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
t1 = ENUM_UNDERLYING_TYPE (t1);
if (TREE_CODE (t2) != VOID_TYPE)
{
- if (enum_and_int_p != NULL)
- *enum_and_int_p = true;
- if (different_types_p != NULL)
- *different_types_p = true;
+ data->enum_and_int_p = true;
+ data->different_types_p = true;
}
}
else if (TREE_CODE (t2) == ENUMERAL_TYPE
@@ -1137,25 +1148,23 @@ comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
t2 = ENUM_UNDERLYING_TYPE (t2);
if (TREE_CODE (t1) != VOID_TYPE)
{
- if (enum_and_int_p != NULL)
- *enum_and_int_p = true;
- if (different_types_p != NULL)
- *different_types_p = true;
+ data->enum_and_int_p = true;
+ data->different_types_p = true;
}
}
if (t1 == t2)
- return 1;
+ return true;
/* Different classes of types can't be compatible. */
if (TREE_CODE (t1) != TREE_CODE (t2))
- return 0;
+ return false;
/* Qualifiers must match. C99 6.7.3p9 */
if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
- return 0;
+ return false;
/* Allow for two different type nodes which have essentially the same
definition. Note that we already checked for equality of the type
@@ -1163,14 +1172,16 @@ comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
if (TREE_CODE (t1) != ARRAY_TYPE
&& TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
- return 1;
+ return true;
+
+ int attrval;
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
if (!(attrval = comp_type_attributes (t1, t2)))
- return 0;
+ return false;
- /* 1 if no need for warning yet, 2 if warning cause has been seen. */
- val = 0;
+ if (2 == attrval)
+ data->warning_needed = true;
switch (TREE_CODE (t1))
{
@@ -1196,16 +1207,11 @@ comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
case POINTER_TYPE:
/* Do not remove mode information. */
if (TYPE_MODE (t1) != TYPE_MODE (t2))
- break;
- val = (TREE_TYPE (t1) == TREE_TYPE (t2)
- ? 1 : comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
- enum_and_int_p, different_types_p));
- break;
+ return false;
+ return comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), data);
case FUNCTION_TYPE:
- val = function_types_compatible_p (t1, t2, enum_and_int_p,
- different_types_p);
- break;
+ return function_types_compatible_p (t1, t2, data);
case ARRAY_TYPE:
{
@@ -1213,21 +1219,16 @@ comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
tree d2 = TYPE_DOMAIN (t2);
bool d1_variable, d2_variable;
bool d1_zero, d2_zero;
- val = 1;
/* Target types must match incl. qualifiers. */
- if (TREE_TYPE (t1) != TREE_TYPE (t2)
- && (val = comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
- enum_and_int_p,
- different_types_p)) == 0)
- return 0;
-
- if (different_types_p != NULL
- && (d1 == NULL_TREE) != (d2 == NULL_TREE))
- *different_types_p = true;
+ if (!comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), data))
+ return false;
+
+ if ((d1 == NULL_TREE) != (d2 == NULL_TREE))
+ data->different_types_p = true;
/* Sizes must match unless one is missing or variable. */
if (d1 == NULL_TREE || d2 == NULL_TREE || d1 == d2)
- break;
+ return true;
d1_zero = !TYPE_MAX_VALUE (d1);
d2_zero = !TYPE_MAX_VALUE (d2);
@@ -1241,51 +1242,37 @@ comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
d1_variable = d1_variable || (d1_zero && C_TYPE_VARIABLE_SIZE (t1));
d2_variable = d2_variable || (d2_zero && C_TYPE_VARIABLE_SIZE (t2));
- if (different_types_p != NULL
- && d1_variable != d2_variable)
- *different_types_p = true;
+ if (d1_variable != d2_variable)
+ data->different_types_p = true;
if (d1_variable || d2_variable)
- break;
+ return true;
if (d1_zero && d2_zero)
- break;
+ return true;
if (d1_zero || d2_zero
|| !tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
|| !tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)))
- val = 0;
+ return false;
- break;
+ return true;
}
case ENUMERAL_TYPE:
case RECORD_TYPE:
case UNION_TYPE:
- if (val != 1 && false)
+ if (false)
{
- tree a1 = TYPE_ATTRIBUTES (t1);
- tree a2 = TYPE_ATTRIBUTES (t2);
-
- if (! attribute_list_contained (a1, a2)
- && ! attribute_list_contained (a2, a1))
- break;
-
- val = tagged_types_tu_compatible_p (t1, t2, enum_and_int_p,
- different_types_p);
-
- if (attrval != 2)
- return val;
+ return tagged_types_tu_compatible_p (t1, t2, data);
}
- break;
+ return false;
case VECTOR_TYPE:
- val = (known_eq (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2))
- && comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
- enum_and_int_p, different_types_p));
- break;
+ return known_eq (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2))
+ && comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2), data);
default:
- break;
+ return false;
}
- return attrval == 2 && val == 1 ? 2 : val;
+ gcc_unreachable ();
}
/* Return 1 if TTL and TTR are pointers to types that are equivalent, ignoring
@@ -1293,7 +1280,7 @@ comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p,
different named addresses, then we must determine if one address space is a
subset of the other. */
-static int
+static bool
comp_target_types (location_t location, tree ttl, tree ttr)
{
int val;
@@ -1395,17 +1382,13 @@ free_all_tagged_tu_seen_up_to (const struct tagged_tu_seen_cache *tu_til)
/* Return 1 if two 'struct', 'union', or 'enum' types T1 and T2 are
compatible. If the two types are not the same (which has been
- checked earlier), this can only happen when multiple translation
- units are being compiled. See C99 6.2.7 paragraph 1 for the exact
- rules. ENUM_AND_INT_P and DIFFERENT_TYPES_P are as in
- comptypes_internal. */
+ checked earlier). */
-static int
+static bool
tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
- bool *enum_and_int_p, bool *different_types_p)
+ struct comptypes_data* data)
{
tree s1, s2;
- bool needs_warning = false;
/* We have to verify that the tags of the types are the same. This
is harder than it looks because this may be a typedef, so we have
@@ -1513,8 +1496,7 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
if (DECL_NAME (s1) != DECL_NAME (s2))
break;
- result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
- enum_and_int_p, different_types_p);
+ result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), data);
if (result != 1 && !DECL_NAME (s1))
break;
@@ -1523,8 +1505,6 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
tu->val = 0;
return 0;
}
- if (result == 2)
- needs_warning = true;
if (TREE_CODE (s1) == FIELD_DECL
&& simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
@@ -1536,7 +1516,6 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
}
if (!s1 && !s2)
{
- tu->val = needs_warning ? 2 : 1;
return tu->val;
}
@@ -1550,8 +1529,7 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
int result;
result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
- enum_and_int_p,
- different_types_p);
+ data);
if (result != 1 && !DECL_NAME (s1))
continue;
@@ -1560,8 +1538,6 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
tu->val = 0;
return 0;
}
- if (result == 2)
- needs_warning = true;
if (TREE_CODE (s1) == FIELD_DECL
&& simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
@@ -1577,7 +1553,6 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
return 0;
}
}
- tu->val = needs_warning ? 2 : 1;
return tu->val;
}
@@ -1599,12 +1574,9 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
if (TREE_CODE (s1) != TREE_CODE (s2)
|| DECL_NAME (s1) != DECL_NAME (s2))
break;
- result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
- enum_and_int_p, different_types_p);
+ result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2), data);
if (result == 0)
break;
- if (result == 2)
- needs_warning = true;
if (TREE_CODE (s1) == FIELD_DECL
&& simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
@@ -1614,7 +1586,7 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
if (s1 && s2)
tu->val = 0;
else
- tu->val = needs_warning ? 2 : 1;
+ tu->val = 1;
return tu->val;
}
@@ -1631,9 +1603,9 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
Otherwise, the argument types must match.
ENUM_AND_INT_P and DIFFERENT_TYPES_P are as in comptypes_internal. */
-static int
+static bool
function_types_compatible_p (const_tree f1, const_tree f2,
- bool *enum_and_int_p, bool *different_types_p)
+ struct comptypes_data *data)
{
tree args1, args2;
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
@@ -1654,16 +1626,15 @@ function_types_compatible_p (const_tree f1, const_tree f2,
if (TYPE_VOLATILE (ret2))
ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2),
TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE);
- val = comptypes_internal (ret1, ret2, enum_and_int_p, different_types_p);
+ val = comptypes_internal (ret1, ret2, data);
if (val == 0)
return 0;
args1 = TYPE_ARG_TYPES (f1);
args2 = TYPE_ARG_TYPES (f2);
- if (different_types_p != NULL
- && (args1 == NULL_TREE) != (args2 == NULL_TREE))
- *different_types_p = true;
+ if ((args1 == NULL_TREE) != (args2 == NULL_TREE))
+ data->different_types_p = true;
/* An unspecified parmlist matches any specified parmlist
whose argument types don't need default promotions. */
@@ -1679,8 +1650,11 @@ function_types_compatible_p (const_tree f1, const_tree f2,
If they don't match, ask for a warning (but no error). */
if (TYPE_ACTUAL_ARG_TYPES (f1)
&& type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1),
- enum_and_int_p, different_types_p) != 1)
- val = 2;
+ data) != 1)
+ {
+ val = 1;
+ data->warning_needed = true;
+ }
return val;
}
if (args2 == NULL_TREE)
@@ -1691,35 +1665,32 @@ function_types_compatible_p (const_tree f1, const_tree f2,
return 0;
if (TYPE_ACTUAL_ARG_TYPES (f2)
&& type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2),
- enum_and_int_p, different_types_p) != 1)
- val = 2;
+ data) != 1)
+ {
+ val = 1;
+ data->warning_needed = true;
+ }
return val;
}
/* Both types have argument lists: compare them and propagate results. */
- val1 = type_lists_compatible_p (args1, args2, enum_and_int_p,
- different_types_p);
- return val1 != 1 ? val1 : val;
+ val1 = type_lists_compatible_p (args1, args2, data);
+ return val1;
}
/* Check two lists of types for compatibility, returning 0 for
- incompatible, 1 for compatible, or 2 for compatible with
- warning. ENUM_AND_INT_P and DIFFERENT_TYPES_P are as in
- comptypes_internal. */
+ incompatible, 1 for compatible. ENUM_AND_INT_P and
+ DIFFERENT_TYPES_P are as in comptypes_internal. */
-static int
+static bool
type_lists_compatible_p (const_tree args1, const_tree args2,
- bool *enum_and_int_p, bool *different_types_p)
+ struct comptypes_data *data)
{
- /* 1 if no need for warning yet, 2 if warning cause has been seen. */
- int val = 1;
- int newval = 0;
-
while (1)
{
tree a1, mv1, a2, mv2;
if (args1 == NULL_TREE && args2 == NULL_TREE)
- return val;
+ return true;
/* If one list is shorter than the other,
they fail to match. */
if (args1 == NULL_TREE || args2 == NULL_TREE)
@@ -1740,9 +1711,8 @@ type_lists_compatible_p (const_tree args1, const_tree args2,
means there is supposed to be an argument
but nothing is specified about what type it has.
So match anything that self-promotes. */
- if (different_types_p != NULL
- && (a1 == NULL_TREE) != (a2 == NULL_TREE))
- *different_types_p = true;
+ if ((a1 == NULL_TREE) != (a2 == NULL_TREE))
+ data->different_types_p = true;
if (a1 == NULL_TREE)
{
if (c_type_promotes_to (a2) != a2)
@@ -1757,11 +1727,9 @@ type_lists_compatible_p (const_tree args1, const_tree args2,
else if (TREE_CODE (a1) == ERROR_MARK
|| TREE_CODE (a2) == ERROR_MARK)
;
- else if (!(newval = comptypes_internal (mv1, mv2, enum_and_int_p,
- different_types_p)))
+ else if (!comptypes_internal (mv1, mv2, data))
{
- if (different_types_p != NULL)
- *different_types_p = true;
+ data->different_types_p = true;
/* Allow wait (union {union wait *u; int *i} *)
and wait (union wait *) to be compatible. */
if (TREE_CODE (a1) == UNION_TYPE
@@ -1782,8 +1750,7 @@ type_lists_compatible_p (const_tree args1, const_tree args2,
? c_build_qualified_type (TYPE_MAIN_VARIANT (mv3),
TYPE_QUAL_ATOMIC)
: TYPE_MAIN_VARIANT (mv3));
- if (comptypes_internal (mv3, mv2, enum_and_int_p,
- different_types_p))
+ if (comptypes_internal (mv3, mv2, data))
break;
}
if (memb == NULL_TREE)
@@ -1807,8 +1774,7 @@ type_lists_compatible_p (const_tree args1, const_tree args2,
? c_build_qualified_type (TYPE_MAIN_VARIANT (mv3),
TYPE_QUAL_ATOMIC)
: TYPE_MAIN_VARIANT (mv3));
- if (comptypes_internal (mv3, mv1, enum_and_int_p,
- different_types_p))
+ if (comptypes_internal (mv3, mv1, data))
break;
}
if (memb == NULL_TREE)
@@ -1818,10 +1784,6 @@ type_lists_compatible_p (const_tree args1, const_tree args2,
return 0;
}
- /* comptypes said ok, but record if it said to warn. */
- if (newval > val)
- val = newval;
-
args1 = TREE_CHAIN (args1);
args2 = TREE_CHAIN (args2);
}
@@ -7298,7 +7260,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
tree mvl = ttl;
tree mvr = ttr;
bool is_opaque_pointer;
- int target_cmp = 0; /* Cache comp_target_types () result. */
+ bool target_cmp = false; /* Cache comp_target_types () result. */
addr_space_t asl;
addr_space_t asr;
--
2.30.2
next prev parent reply other threads:[~2023-08-26 16:21 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-26 16:19 c23 type compatibility rules, v2 Martin Uecker
2023-08-26 16:20 ` Martin Uecker [this message]
2023-09-06 20:59 ` [C PATCH 1/6] c: reorganize recursive type checking Joseph Myers
2023-09-10 8:17 ` [C PATCH 1/6 v2] " Martin Uecker
2023-09-11 20:28 ` Joseph Myers
2023-08-26 16:22 ` [C PATCH 2/6] c23: recursive type checking of tagged type Martin Uecker
2023-11-07 23:06 ` Joseph Myers
2023-08-26 16:23 ` [C PATCH 3/6] c23: tag compatibility rules for struct and unions Martin Uecker
2023-11-07 23:18 ` Joseph Myers
2023-08-26 16:24 ` [C PATCH 4/6] c23: tag compatibility rules for enums Martin Uecker
2023-11-07 23:20 ` Joseph Myers
2023-08-26 16:25 ` [C PATCH 5/6] c23: aliasing of compatible tagged types Martin Uecker
2023-08-26 16:26 ` [C PATCH 6/6] c23: construct composite type for " Martin Uecker
2023-11-07 23:45 ` Joseph Myers
2023-08-26 16:26 ` [C PATCH] c: flag for tag compatibility rules Martin Uecker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1df29de95ff41a02ffd218f4cd69f8f93df35321.camel@tugraz.at \
--to=uecker@tugraz.at \
--cc=gcc-patches@gcc.gnu.org \
--cc=joseph@codesourcery.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).