aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2021-06-06 11:37:45 +0200
committerEric Botcazou <ebotcazou@adacore.com>2021-06-06 11:41:30 +0200
commita589877a0036fc2f66b7a957859940c53efdc7c9 (patch)
treea6bc26893ec860b9b4411e2ef71520937c894b14 /gcc/c
parent28c62475050d2ac6c243580e1130a87308e1e907 (diff)
downloadgcc-a589877a0036fc2f66b7a957859940c53efdc7c9.zip
gcc-a589877a0036fc2f66b7a957859940c53efdc7c9.tar.gz
gcc-a589877a0036fc2f66b7a957859940c53efdc7c9.tar.bz2
Fix thinko in new warning on type punning for storage order purposes
In C, unlike in Ada, the storage order of arrays is that of their component type, so you need to look at it when deciding to warn. And the PR complains about a bogus warning on the assignment of a pointer returned by alloca or malloc, so this also fixes that. gcc/c PR c/100920 * c-decl.c (finish_struct): Fix thinko in previous change. * c-typeck.c (convert_for_assignment): Do not warn on pointer assignment and initialization for storage order purposes if the RHS is a call to a DECL_IS_MALLOC function. gcc/testsuite/ * gcc.dg/sso-14.c: New test.
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/c-decl.c19
-rw-r--r--gcc/c/c-typeck.c23
2 files changed, 31 insertions, 11 deletions
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 28f851b..a86792b 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -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.
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index be3f4f0..daa2e12 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -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,