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