public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-1242] Fix thinko in new warning on type punning for storage order purposes
@ 2021-06-06  9:43 Eric Botcazou
  0 siblings, 0 replies; only message in thread
From: Eric Botcazou @ 2021-06-06  9:43 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a589877a0036fc2f66b7a957859940c53efdc7c9

commit r12-1242-ga589877a0036fc2f66b7a957859940c53efdc7c9
Author: Eric Botcazou <ebotcazou@adacore.com>
Date:   Sun Jun 6 11:37:45 2021 +0200

    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:
---
 gcc/c/c-decl.c                | 19 ++++++++++++----
 gcc/c/c-typeck.c              | 23 ++++++++++++++-----
 gcc/testsuite/gcc.dg/sso-14.c | 53 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 84 insertions(+), 11 deletions(-)

diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 28f851b9d0b..a86792bbe06 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 be3f4f09f6e..daa2e12a25f 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 00000000000..af98145569e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sso-14.c
@@ -0,0 +1,53 @@
+/* PR c/100920 */
+/* Testcase by George Thopas <george.thopas@gmail.com> */
+
+/* { dg-do compile } */
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#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;
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-06-06  9:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-06  9:43 [gcc r12-1242] Fix thinko in new warning on type punning for storage order purposes Eric Botcazou

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).