@@ -8854,12 +8854,21 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
}
}
+ /* Warn on problematic type punning for storage order purposes. */
if (TREE_CODE (t) == UNION_TYPE
- && AGGREGATE_TYPE_P (TREE_TYPE (field))
- && TYPE_REVERSE_STORAGE_ORDER (t)
- != TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (field)))
- warning_at (DECL_SOURCE_LOCATION (field), OPT_Wscalar_storage_order,
- "type punning toggles scalar storage order");
+ && TREE_CODE (field) == FIELD_DECL
+ && AGGREGATE_TYPE_P (TREE_TYPE (field)))
+ {
+ tree ftype = TREE_TYPE (field);
+ if (TREE_CODE (ftype) == ARRAY_TYPE)
+ ftype = strip_array_types (ftype);
+ if (RECORD_OR_UNION_TYPE_P (ftype)
+ && TYPE_REVERSE_STORAGE_ORDER (ftype)
+ != TYPE_REVERSE_STORAGE_ORDER (t))
+ warning_at (DECL_SOURCE_LOCATION (field),
+ OPT_Wscalar_storage_order,
+ "type punning toggles scalar storage order");
+ }
}
/* Now we have the truly final field list.
@@ -7295,6 +7295,8 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
&& (AGGREGATE_TYPE_P (ttl) && TYPE_REVERSE_STORAGE_ORDER (ttl))
!= (AGGREGATE_TYPE_P (ttr) && TYPE_REVERSE_STORAGE_ORDER (ttr)))
{
+ tree t;
+
switch (errtype)
{
case ic_argpass:
@@ -7307,14 +7309,23 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
"scalar storage order", parmnum, rname);
break;
case ic_assign:
- warning_at (location, OPT_Wscalar_storage_order,
- "assignment to %qT from pointer type %qT with "
- "incompatible scalar storage order", type, rhstype);
+ /* Do not warn if the RHS is a call to a function that returns a
+ pointer that is not an alias. */
+ if (TREE_CODE (rhs) != CALL_EXPR
+ || (t = get_callee_fndecl (rhs)) == NULL_TREE
+ || !DECL_IS_MALLOC (t))
+ warning_at (location, OPT_Wscalar_storage_order,
+ "assignment to %qT from pointer type %qT with "
+ "incompatible scalar storage order", type, rhstype);
break;
case ic_init:
- warning_at (location, OPT_Wscalar_storage_order,
- "initialization of %qT from pointer type %qT with "
- "incompatible scalar storage order", type, rhstype);
+ /* Likewise. */
+ if (TREE_CODE (rhs) != CALL_EXPR
+ || (t = get_callee_fndecl (rhs)) == NULL_TREE
+ || !DECL_IS_MALLOC (t))
+ warning_at (location, OPT_Wscalar_storage_order,
+ "initialization of %qT from pointer type %qT with "
+ "incompatible scalar storage order", type, rhstype);
break;
case ic_return:
warning_at (location, OPT_Wscalar_storage_order,