When checking alignment of packed member, we should only check the
non-pointer data member.

gcc/c-family/

        PR c++/88664
        * c-family/c-warn.c (check_alignment_of_packed_member): Only
        check the non-pointer data member.

gcc/testsuite/

        PR c++/88664
        * gcc.dg/pr88664-1.c: New test.
        * g++.dg/pr88664-2.C: Likewise.
---
 gcc/c-family/c-warn.c            |  8 +++++---
 gcc/testsuite/g++.dg/pr88664-2.C | 21 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/pr88664-1.c | 19 +++++++++++++++++++
 3 files changed, 45 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/pr88664-2.C
 create mode 100644 gcc/testsuite/gcc.dg/pr88664-1.c

diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index 070934ab2b6..97b92d3493a 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -2687,14 +2687,16 @@ warn_for_multistatement_macros (location_t body_loc, 
location_t next_loc,
            "this %qs clause", guard_tinfo_to_string (keyword));
 }
 
-/* Return struct or union type if the alignment of data memeber, FIELD,
-   is less than the alignment of TYPE.  Otherwise, return NULL_TREE.  */
+/* Return struct or union type if the alignment of non-pointer data
+   memeber, FIELD, is less than the alignment of TYPE.  Otherwise,
+   return NULL_TREE.  */
 
 static tree
 check_alignment_of_packed_member (tree type, tree field)
 {
-  /* Check alignment of the data member.  */
+  /* Check alignment of the non-pointer data member.  */
   if (TREE_CODE (field) == FIELD_DECL
+      && !POINTER_TYPE_P (TREE_TYPE (field))
       && (DECL_PACKED (field)
          || TYPE_PACKED (TREE_TYPE (field))))
     {
diff --git a/gcc/testsuite/g++.dg/pr88664-2.C b/gcc/testsuite/g++.dg/pr88664-2.C
new file mode 100644
index 00000000000..712600cdeb7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr88664-2.C
@@ -0,0 +1,21 @@
+/* PR c++/88664.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct epoll_event
+{
+  short events;
+  void *ptr;
+} __attribute__ ((__packed__));
+
+int *
+foo1 (epoll_event *event)
+{
+  return static_cast <int *> (event->ptr);
+}
+
+int *
+foo2 (epoll_event *event)
+{
+  return event ? static_cast <int *> (event->ptr) : (int *) 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr88664-1.c b/gcc/testsuite/gcc.dg/pr88664-1.c
new file mode 100644
index 00000000000..410167b542c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr88664-1.c
@@ -0,0 +1,19 @@
+/* PR c++/88664.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct data {
+  void *ptr;
+} __attribute__((packed)) var;
+
+int *
+fun1 (void)
+{
+  return (int *)var.ptr;
+}
+
+int *
+fun2 (int i)
+{
+  return i ? (int *)var.ptr : (int *) 0;
+}
-- 
2.20.1

Reply via email to