]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix old thinko in warning on pointer for storage order purposes
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 9 Jun 2021 10:37:47 +0000 (12:37 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Wed, 9 Jun 2021 10:39:52 +0000 (12:39 +0200)
gcc/c
PR c/100920
* c-typeck.c (convert_for_assignment): Test fndecl_built_in_p to
spot built-in functions. 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.

gcc/c/c-typeck.c
gcc/testsuite/gcc.dg/sso-14.c [new file with mode: 0644]

index 51a62c800f79035c4c63c11751a4c7c12a9fa04b..917e670ddd71288171c285ed7aedfdee4b3d05af 100644 (file)
@@ -7294,23 +7294,35 @@ 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:
            /* Do not warn for built-in functions, for example memcpy, since we
               control how they behave and they can be useful in this area.  */
            if (TREE_CODE (rname) != FUNCTION_DECL
-               || !DECL_IS_UNDECLARED_BUILTIN (rname))
+               || !fndecl_built_in_p (rname))
              warning_at (location, OPT_Wscalar_storage_order,
                          "passing argument %d of %qE from incompatible "
                          "scalar storage order", parmnum, rname);
            break;
          case ic_assign:
+           /* 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:
+           /* 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,
                        "initialization of %qT from pointer type %qT with "
                        "incompatible scalar storage order", type, rhstype);
diff --git a/gcc/testsuite/gcc.dg/sso-14.c b/gcc/testsuite/gcc.dg/sso-14.c
new file mode 100644 (file)
index 0000000..8941946
--- /dev/null
@@ -0,0 +1,56 @@
+/* PR c/100920 */
+/* Testcase by George Thopas <george.thopas@gmail.com> */
+
+/* { dg-do compile } */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.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);
+  int same;
+
+  msg1 = malloc (sizeof (t_s12));
+  msg2 = malloc (sizeof (t_u12));
+
+  memset (msg1, 0, sizeof (t_s12));
+  memcpy (msg2, &msg1, sizeof (t_s12));
+  same = memcmp (msg1, msg2, sizeof (t_s12));
+
+  return 0;
+}