c-warn.c (check_address_or_pointer_of_packed_member): Handle the case when rhs is...
authorBernd Edlinger <bernd.edlinger@hotmail.de>
Mon, 28 Jan 2019 13:14:37 +0000 (13:14 +0000)
committerBernd Edlinger <edlinger@gcc.gnu.org>
Mon, 28 Jan 2019 13:14:37 +0000 (13:14 +0000)
2019-01-28  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        * c-warn.c (check_address_or_pointer_of_packed_member): Handle the case
        when rhs is of array type correctly.  Fix handling of nested structures.
        Fix handling of indirect_ref together with nop_expr and/or addr_expr.
        (check_and_warn_address_or_pointer_of_packed_member): Fix handling of
        type casts within nested compound expressions.

testsuite:
2019-01-28  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        * c-c++-common/Waddress-of-packed-member-1.c: Extended test case.
        * c-c++-common/Waddress-of-packed-member-2.c: New test case.

From-SVN: r268337

gcc/c-family/ChangeLog
gcc/c-family/c-warn.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c
gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c [new file with mode: 0644]

index 86efe275366673b2db56ca365e678ea0933cb396..f955449ec1c9b95293479a04209c9300365fcc3b 100644 (file)
@@ -1,3 +1,11 @@
+2019-01-28  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       * c-warn.c (check_address_or_pointer_of_packed_member): Handle the case
+       when rhs is of array type correctly.  Fix handling of nested structures.
+       Fix handling of indirect_ref together with nop_expr and/or addr_expr.
+       (check_and_warn_address_or_pointer_of_packed_member): Fix handling of
+       type casts within nested compound expressions.
+
 2019-01-22  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/88968
index 43b307acafec11f00fcb7e292f0f27a4111f7f3a..e2f3449e69420364361766d524f9030dbf70ba82 100644 (file)
@@ -2725,14 +2725,19 @@ static tree
 check_address_or_pointer_of_packed_member (tree type, tree rhs)
 {
   bool rvalue = true;
+  bool indirect = false;
 
   if (INDIRECT_REF_P (rhs))
-    rhs = TREE_OPERAND (rhs, 0);
+    {
+      rhs = TREE_OPERAND (rhs, 0);
+      STRIP_NOPS (rhs);
+      indirect = true;
+    }
 
   if (TREE_CODE (rhs) == ADDR_EXPR)
     {
       rhs = TREE_OPERAND (rhs, 0);
-      rvalue = false;
+      rvalue = indirect;
     }
 
   if (!POINTER_TYPE_P (type))
@@ -2796,6 +2801,10 @@ check_address_or_pointer_of_packed_member (tree type, tree rhs)
          if (context)
            break;
        }
+      if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE)
+       rvalue = false;
+      if (rvalue)
+       return NULL_TREE;
       rhs = TREE_OPERAND (rhs, 0);
     }
 
@@ -2811,14 +2820,18 @@ check_address_or_pointer_of_packed_member (tree type, tree rhs)
 static void
 check_and_warn_address_or_pointer_of_packed_member (tree type, tree rhs)
 {
-  bool nop_p;
-
-  while (TREE_CODE (rhs) == COMPOUND_EXPR)
-    rhs = TREE_OPERAND (rhs, 1);
+  bool nop_p = false;
+  tree orig_rhs;
 
-  tree orig_rhs = rhs;
-  STRIP_NOPS (rhs);
-  nop_p = orig_rhs != rhs;
+  do
+    {
+      while (TREE_CODE (rhs) == COMPOUND_EXPR)
+       rhs = TREE_OPERAND (rhs, 1);
+      orig_rhs = rhs;
+      STRIP_NOPS (rhs);
+      nop_p |= orig_rhs != rhs;
+    }
+  while (orig_rhs != rhs);
 
   if (TREE_CODE (rhs) == COND_EXPR)
     {
index d4796df223a3f2545f5a63a99e45d2ad8d18058c..ab61b302a6dfaf9c39be242f9d3cac39e2b9b347 100644 (file)
@@ -1,3 +1,8 @@
+2019-01-28  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+       * c-c++-common/Waddress-of-packed-member-1.c: Extended test case.
+       * c-c++-common/Waddress-of-packed-member-2.c: New test case.
+
 2019-01-28  Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
        * gcc.dg/Wattribute-alias.c: Add test for #pragma GCC diagnostic ignored
index a1374fb10f4fce73acfbd7967a9e9c6d9265ad02..afad603dfa249bdd9fadbd51dcd2558119e23415 100644 (file)
@@ -6,6 +6,8 @@ struct t {
   int b;
   int *c;
   int d[10];
+  int *e[1];
+  _Complex float f;
 } __attribute__((packed));
 
 struct t t0;
@@ -17,6 +19,8 @@ struct t *bar();
 struct t (*baz())[10];
 struct t (*bazz())[10][10];
 int *i1;
+int **i2;
+float f0, *f1;
 __UINTPTR_TYPE__ u1;
 __UINTPTR_TYPE__ baa();
 
@@ -40,6 +44,14 @@ void foo (void)
   i1 = t10[0].c;               /* { dg-bogus "may result in an unaligned pointer value" } */
   u1 = (__UINTPTR_TYPE__) &t0; /* { dg-bogus "may result in an unaligned pointer value" } */
   u1 = (__UINTPTR_TYPE__) t1;  /* { dg-bogus "may result in an unaligned pointer value" } */
+  i1 = t10[0].e[0];            /* { dg-bogus "may result in an unaligned pointer value" } */
+  i1 = *&t0.c;                 /* { dg-bogus "may result in an unaligned pointer value" } */
+  i1 = *&*&t0.c;               /* { dg-bogus "may result in an unaligned pointer value" } */
+  f0 = __real__ t0.f;          /* { dg-bogus "may result in an unaligned pointer value" } */
+  f0 = __imag__ t0.f;          /* { dg-bogus "may result in an unaligned pointer value" } */
+  f0 = *&__real__ t0.f;        /* { dg-bogus "may result in an unaligned pointer value" } */
+  f0 = *&__imag__ t0.f;        /* { dg-bogus "may result in an unaligned pointer value" } */
+  i1 = (&t0.c, (int*) 0);      /* { dg-bogus "may result in an unaligned pointer value" } */
   t2 = (struct t**) t10;     /* { dg-warning "may result in an unaligned pointer value" } */
   t2 = (struct t**) t100;    /* { dg-warning "may result in an unaligned pointer value" } */
   t2 = (struct t**) t1;      /* { dg-warning "may result in an unaligned pointer value" } */
@@ -52,4 +64,16 @@ void foo (void)
   i1 = t0.d;                 /* { dg-warning "may result in an unaligned pointer value" } */
   i1 = t1->d;                /* { dg-warning "may result in an unaligned pointer value" } */
   i1 = t10[0].d;             /* { dg-warning "may result in an unaligned pointer value" } */
+  i1 = (int*) &t10[0].e[0];  /* { dg-warning "may result in an unaligned pointer value" } */
+  i1 = (int*) t10[0].e;      /* { dg-warning "may result in an unaligned pointer value" } */
+  i2 = &t10[0].e[0];         /* { dg-warning "may result in an unaligned pointer value" } */
+  i2 = t10[0].e;             /* { dg-warning "may result in an unaligned pointer value" } */
+  i2 = &*&t0.c;              /* { dg-warning "may result in an unaligned pointer value" } */
+  i2 = &*&*&t0.c;            /* { dg-warning "may result in an unaligned pointer value" } */
+  f1 = &__real__ t0.f;       /* { dg-warning "may result in an unaligned pointer value" } */
+  f1 = &__imag__ t0.f;       /* { dg-warning "may result in an unaligned pointer value" } */
+  i1 = (0, (int*) &t0.c);    /* { dg-warning "may result in an unaligned pointer value" } */
+  i1 = (int*) (0, &t0.c);    /* { dg-warning "may result in an unaligned pointer value" } */
+  i1 = (0, (int*)(0, &t0.c));/* { dg-warning "may result in an unaligned pointer value" } */
+  i1 = (int*)(0, 1, (void*)(2, 3, (int*)(4, 5, &t0.c)));/* { dg-warning "may result in an unaligned pointer value" } */
 }
diff --git a/gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c b/gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c
new file mode 100644 (file)
index 0000000..65ec514
--- /dev/null
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-options "-Waddress-of-packed-member" } */
+
+struct r {
+  int a[10];
+  int b[10][10];
+  int ****i4;
+};
+
+struct s {
+  char c;
+  struct r p;
+} __attribute__((packed));
+
+struct t {
+  char c;
+  struct r p __attribute__((packed));
+  struct r u;
+};
+
+struct s s0;
+struct t t0;
+int *i0;
+
+void foo (void)
+{
+  i0 = s0.p.a;               /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = t0.p.a;               /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = s0.p.b[0];            /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = t0.p.b[0];            /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = &s0.p.a[0];           /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = &t0.p.a[0];           /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = &s0.p.b[0][0];        /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = &t0.p.b[0][0];        /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = *s0.p.b;              /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = *t0.p.b;              /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = &**s0.p.b;            /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = &**t0.p.b;            /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = **&s0.p.b;            /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = **&t0.p.b;            /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = &*s0.p.a;             /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = &*t0.p.a;             /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = *&s0.p.a;             /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = *&t0.p.a;             /* { dg-warning "may result in an unaligned pointer value" } */
+  i0 = t0.u.a;                 /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = t0.u.b[0];              /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = &t0.u.a[0];             /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = &t0.u.b[0][0];          /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = *t0.u.b;                /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = &*t0.u.a;               /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = &**t0.u.b;              /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = ***s0.p.i4;             /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = ***t0.p.i4;             /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = ****&s0.p.i4;           /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = ****&t0.p.i4;           /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = &****s0.p.i4;           /* { dg-bogus "may result in an unaligned pointer value" } */
+  i0 = &****t0.p.i4;           /* { dg-bogus "may result in an unaligned pointer value" } */
+}