if (t == NULL_TREE)
{
t = make_node (code);
+ if (flag_isoc23 && code != ENUMERAL_TYPE)
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
pushtag (input_location, name, t);
}
}
the forward-reference will be altered into a real type. */
ref = make_node (code);
+ if (flag_isoc23 && code != ENUMERAL_TYPE)
+ SET_TYPE_STRUCTURAL_EQUALITY (ref);
if (code == ENUMERAL_TYPE)
{
/* Give the type a default layout like unsigned int
if (ref == NULL_TREE || TREE_CODE (ref) != code)
{
ref = make_node (code);
+ if (flag_isoc23)
+ SET_TYPE_STRUCTURAL_EQUALITY (ref);
pushtag (loc, name, ref);
}
return false;
}
+/* Recompute TYPE_CANONICAL for variants of the type including qualified
+ versions of the type and related pointer types after an aggregate type
+ has been finalized.
+ Will not update array types, pointers to array types, function
+ types and other derived types created while the type was still
+ incomplete, those will remain TYPE_STRUCTURAL_EQUALITY_P. */
+
+static void
+c_update_type_canonical (tree t)
+{
+ for (tree x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
+ {
+ if (x != t && TYPE_STRUCTURAL_EQUALITY_P (x))
+ {
+ if (TYPE_QUALS (x) == TYPE_QUALS (t))
+ TYPE_CANONICAL (x) = TYPE_CANONICAL (t);
+ else if (TYPE_CANONICAL (t) != t
+ || check_qualified_type (x, t, TYPE_QUALS (x)))
+ TYPE_CANONICAL (x)
+ = build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));
+ else
+ TYPE_CANONICAL (x) = x;
+ }
+ else if (x != t)
+ continue;
+ for (tree p = TYPE_POINTER_TO (x); p; p = TYPE_NEXT_PTR_TO (p))
+ {
+ if (!TYPE_STRUCTURAL_EQUALITY_P (p))
+ continue;
+ if (TYPE_CANONICAL (x) != x || TYPE_REF_CAN_ALIAS_ALL (p))
+ TYPE_CANONICAL (p)
+ = build_pointer_type_for_mode (TYPE_CANONICAL (x), TYPE_MODE (p),
+ false);
+ else
+ TYPE_CANONICAL (p) = p;
+ c_update_type_canonical (p);
+ }
+ }
+}
/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
/* Set type canonical based on equivalence class. */
if (flag_isoc23)
{
- if (NULL == c_struct_htab)
+ if (c_struct_htab == NULL)
c_struct_htab = hash_table<c_struct_hasher>::create_ggc (61);
hashval_t hash = c_struct_hasher::hash (t);
+ gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
tree *e = c_struct_htab->find_slot_with_hash (t, hash, INSERT);
if (*e)
TYPE_CANONICAL (t) = *e;
TYPE_CANONICAL (t) = t;
*e = t;
}
+ c_update_type_canonical (t);
}
tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
/* Otherwise, create a new type node and link it into the cache. */
tree n = make_node (code1);
+ SET_TYPE_STRUCTURAL_EQUALITY (n);
TYPE_NAME (n) = TYPE_NAME (t1);
struct composite_cache cache2 = { t1, t2, n, cache };
TYPE_STUB_DECL (n) = pushdecl (build_decl (input_location, TYPE_DECL,
NULL_TREE, n));
- n = finish_struct(input_location, n, fields, attributes, NULL, &expr);
+ n = finish_struct (input_location, n, fields, attributes, NULL,
+ &expr);
n = qualify_type (n, t1);