From: Eric Botcazou Date: Sun, 6 Jun 2021 09:37:45 +0000 (+0200) Subject: Fix thinko in new warning on type punning for storage order purposes X-Git-Tag: upstream/12.2.0~7455 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a589877a0036fc2f66b7a957859940c53efdc7c9;p=platform%2Fupstream%2Fgcc.git 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. --- 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, diff --git a/gcc/testsuite/gcc.dg/sso-14.c b/gcc/testsuite/gcc.dg/sso-14.c new file mode 100644 index 0000000..af98145 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sso-14.c @@ -0,0 +1,53 @@ +/* PR c/100920 */ +/* Testcase by George Thopas */ + +/* { dg-do compile } */ + +#include +#include + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define REV_ENDIANNESS __attribute__((scalar_storage_order("big-endian"))) +#else +#define REV_ENDIANNESS __attribute__((scalar_storage_order("little-endian"))) +#endif + +struct s_1 { + int val; +} REV_ENDIANNESS; + +typedef struct s_1 t_1; + +struct s_2 { + char val; +} REV_ENDIANNESS; + +typedef struct s_2 t_2; + +struct s12 { + t_1 a[1]; + t_2 b[1]; +} REV_ENDIANNESS; + +typedef struct s12 t_s12; + +union u12 { + t_1 a[1]; + t_2 b[1]; +} REV_ENDIANNESS; + +typedef union u12 t_u12; + +int main(void) +{ + t_s12 *msg1 = __builtin_alloca(10); + t_u12 *msg2 = __builtin_alloca(10); + + msg1 = malloc (sizeof (t_s12)); + msg2 = malloc (sizeof (t_u12)); + + msg1->a[0].val = 0; + msg2->a[0].val = 0; + + return 0; +}