Hi,

unfortunately there are some more issues with -Waddress-of-packed-member, that 
show that my previous
patch was not yet complete.

That is a bogus warning, in C and C++ (see addition in test case 1), and a 
couple of missing warnings
in C++ (test case 2).

The latter warning regressions were accidentally introduced by my previous 
patch, sorry.

As a side note, the generic tree for an expression like struct.array is folded 
differently by
C and C++ FE.  While C folds that to &struct.array, C++ folds it to 
struct.array, without the
ADDR_EXPR.  That might help to explain why this needs to be done in this 
slightly confusing way.


Fixed the warning regression, and added some more test cases.


Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?


Thanks
Bernd.
2019-01-22  Bernd Edlinger  <bernd.edlin...@hotmail.de>

	PR c/88928
	* 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.

testsuite:
2019-01-22  Bernd Edlinger  <bernd.edlin...@hotmail.de>

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

Index: gcc/c-family/c-warn.c
===================================================================
--- gcc/c-family/c-warn.c	(revision 268119)
+++ gcc/c-family/c-warn.c	(working copy)
@@ -2796,6 +2796,10 @@ check_address_or_pointer_of_packed_membe
 	  if (context)
 	    break;
 	}
+      if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE)
+	rvalue = false;
+      if (rvalue)
+	return NULL_TREE;
       rhs = TREE_OPERAND (rhs, 0);
     }
 
Index: gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c
===================================================================
--- gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c	(revision 268119)
+++ gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c	(working copy)
@@ -6,6 +6,7 @@ struct t {
   int b;
   int *c;
   int d[10];
+  int *e[1];
 } __attribute__((packed));
 
 struct t t0;
@@ -40,6 +41,7 @@ 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" } */
   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 +54,6 @@ 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" } */
 }
Index: gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c
===================================================================
--- gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c	(revision 0)
+++ gcc/testsuite/c-c++-common/Waddress-of-packed-member-2.c	(working copy)
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-Waddress-of-packed-member" } */
+
+struct r {
+  int a[10];
+  int b[10][10];
+};
+
+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 = 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" } */
+}

Reply via email to