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