public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* V4 [PATCH] C/C++: Add -Waddress-of-packed-member
@ 2018-09-25 15:47 H.J. Lu
  2018-11-04 15:16 ` PING: " H.J. Lu
  2018-12-13 20:50 ` Jason Merrill
  0 siblings, 2 replies; 23+ messages in thread
From: H.J. Lu @ 2018-09-25 15:47 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Joseph Myers, Martin Sebor, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 7755 bytes --]

On Fri, Aug 31, 2018 at 2:04 PM, Jason Merrill <jason@redhat.com> wrote:
> On 07/23/2018 05:24 PM, H.J. Lu wrote:
>>
>> On Mon, Jun 18, 2018 at 12:26 PM, Joseph Myers <joseph@codesourcery.com>
>> wrote:
>>>
>>> On Mon, 18 Jun 2018, Jason Merrill wrote:
>>>
>>>> On Mon, Jun 18, 2018 at 11:59 AM, Joseph Myers <joseph@codesourcery.com>
>>>> wrote:
>>>>>
>>>>> On Mon, 18 Jun 2018, Jason Merrill wrote:
>>>>>
>>>>>>> +  if (TREE_CODE (rhs) == COND_EXPR)
>>>>>>> +    {
>>>>>>> +      /* Check the THEN path first.  */
>>>>>>> +      tree op1 = TREE_OPERAND (rhs, 1);
>>>>>>> +      context = check_address_of_packed_member (type, op1);
>>>>>>
>>>>>>
>>>>>> This should handle the GNU extension of re-using operand 0 if operand
>>>>>> 1 is omitted.
>>>>>
>>>>>
>>>>> Doesn't that just use a SAVE_EXPR?
>>>>
>>>>
>>>> Hmm, I suppose it does, but many places in the compiler seem to expect
>>>> that it produces a COND_EXPR with TREE_OPERAND 1 as NULL_TREE.
>>>
>>>
>>> Maybe that's used somewhere inside the C++ front end.  For C a SAVE_EXPR
>>> is produced directly.
>>
>>
>> Here is the updated patch.  Changes from the last one:
>>
>> 1. Handle COMPOUND_EXPR.
>> 2. Fixed typos in comments.
>> 3. Combined warn_for_pointer_of_packed_member and
>> warn_for_address_of_packed_member into
>> warn_for_address_or_pointer_of_packed_member.
>
>
>> c.i:4:33: warning: converting a packed ‘struct C *’ pointer increases the
>> alignment of ‘long int *’ pointer from 1 to 8 [-Waddress-of-packed-member]
>
>
> I think this would read better as
>
> c.i:4:33: warning: converting a packed ‘struct C *’ pointer (alignment 1) to
> ‘long int *’ (alignment 8) may result in an unaligned pointer value
> [-Waddress-of-packed-member]

Fixed.

>> +      while (TREE_CODE (base) == ARRAY_REF)
>> +       base = TREE_OPERAND (base, 0);
>> +      if (TREE_CODE (base) != COMPONENT_REF)
>> +       return NULL_TREE;
>
>
> Are you deliberately not handling the other handled_component_p cases? If
> so, there should be a comment.

I changed it to

     while (handled_component_p (base))
        {
          enum tree_code code = TREE_CODE (base);
          if (code == COMPONENT_REF)
            break;
          switch (code)
            {
            case ARRAY_REF:
              base = TREE_OPERAND (base, 0);
              break;
            default:
              /* FIXME: Can it ever happen?  */
              gcc_unreachable ();
              break;
            }
        }

Is there a testcase to trigger this ICE? I couldn't find one.

>> +  /* Check alignment of the object.  */
>> +  if (TREE_CODE (object) == COMPONENT_REF)
>> +    {
>> +      field = TREE_OPERAND (object, 1);
>> +      if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
>> +       {
>> +         type_align = TYPE_ALIGN (type);
>> +         context = DECL_CONTEXT (field);
>> +         record_align = TYPE_ALIGN (context);
>> +         if ((record_align % type_align) != 0)
>> +           return context;
>> +       }
>> +    }
>
>
> Why doesn't this recurse?  What if you have a packed field three
> COMPONENT_REFs down?

My patch works on
[hjl@gnu-cfl-1 pr51628-4]$ cat x.i
struct A { int i; } __attribute__ ((packed));
struct B { struct A a; };
struct C { struct B b; };

extern struct C *p;

int* g8 (void) { return &p->b.a.i; }
[hjl@gnu-cfl-1 pr51628-4]$ make x.s
/export/build/gnu/tools-build/gcc-debug/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/tools-build/gcc-debug/build-x86_64-linux/gcc/ -O2
-S x.i
x.i: In function ‘g8’:
x.i:7:25: warning: taking address of packed member of ‘struct A’ may
result in an unaligned pointer value [-Waddress-of-packed-member]
7 | int* g8 (void) { return &p->b.a.i; }
  |                         ^~~~~~~~~
[hjl@gnu-cfl-1 pr51628-4]$

If it isn't what you had in mind, can you give me a testcase?

>> +  if (TREE_CODE (rhs) == COND_EXPR)
>> +    {
>> +      /* Check the THEN path first.  */
>> +      tree op1 = TREE_OPERAND (rhs, 1);
>> +      context = check_address_of_packed_member (type, op1);
>> +      if (context)
>> +       rhs = op1;
>> +      else
>> +       {
>> +         /* Check the ELSE path.  */
>> +         rhs = TREE_OPERAND (rhs, 2);
>> +         context = check_address_of_packed_member (type, rhs);
>> +       }
>> +    }
>
>
> Likewise, what if you have more levels of COND_EXPR?  Or COMPOUND_EXPR
> within COND_EXPR?

Fixed, now I got

[hjl@gnu-cfl-1 pr51628-5]$ cat z.i
struct A {
  int i;
} __attribute__ ((packed));

int*
foo3 (struct A *p1, int *q1, int *q2, struct A *p2)
{
  return (q1
          ? &p1->i
          : (q2 ? &p2->i : q2));
}
[hjl@gnu-cfl-1 pr51628-5]$ make z.s
/export/build/gnu/tools-build/gcc-debug/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/tools-build/gcc-debug/build-x86_64-linux/gcc/ -O2
-S z.i
z.i: In function ‘foo3’:
z.i:9:13: warning: taking address of packed member of ‘struct A’ may
result in an unaligned pointer value [-Waddress-of-packed-member]
9 |           ? &p1->i
  |             ^~~~~~
z.i:10:19: warning: taking address of packed member of ‘struct A’ may
result in an unaligned pointer value [-Waddress-of-packed-member]
10 |           : (q2 ? &p2->i : q2));
   |                   ^~~~~~
[hjl@gnu-cfl-1 pr51628-5]$

>> @@ -7470,6 +7470,9 @@ convert_for_arg_passing (tree type, tree val,
>> tsubst_flags_t complain)
>> +  warn_for_address_or_pointer_of_packed_member (true, type, val);
>
>
>> @@ -8914,6 +8914,8 @@ convert_for_assignment (tree type, tree rhs,
>> +  warn_for_address_or_pointer_of_packed_member (true, type, rhs);
>
>
> Why would address_p be true in these calls?  It seems that you are warning
> at the point of assignment but looking for the warning about taking the
> address rather than the one about assignment.

It happens only with C for incompatible pointer conversion:

[hjl@gnu-cfl-1 pr51628-2]$ cat c.i
struct B { int i; };
struct C { struct B b; } __attribute__ ((packed));

long* g8 (struct C *p) { return p; }
[hjl@gnu-cfl-1 pr51628-2]$ make c.s
/export/build/gnu/tools-build/gcc-debug/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/tools-build/gcc-debug/build-x86_64-linux/gcc/ -O2
-S c.i
c.i: In function ‘g8’:
c.i:4:33: warning: returning ‘struct C *’ from a function with
incompatible return type ‘long int *’ [-Wincompatible-pointer-types]
4 | long* g8 (struct C *p) { return p; }
  |                                 ^
c.i:4:18: warning: converting a packed ‘struct C *’ pointer (alignment
1) to ‘long int *’ (alignment 8) may may result in an unaligned
pointer value [-Waddress-of-packed-member]
4 | long* g8 (struct C *p) { return p; }
  |                  ^
c.i:2:8: note: defined here
2 | struct C { struct B b; } __attribute__ ((packed));
  |        ^
[hjl@gnu-cfl-1 pr51628-2]$

address_p is false in this case and rhs is PARM_DECL, VAR_DECL or
NOP_EXPR.  This comes from convert_for_assignment in c/c-typeck.c.

For other compatible pointer assignment, address_p is true and rhs is
ADDR_EXPR, PARM_DECL, VAR_DECL or NOP_EXPR.   Check
for  ADDR_EXPR won't work.

address_p isn't an appropriate parameter name.  I changed it to convert_p
to indicate that it is an incompatible pointer type conversion.

> If you want to warn about taking the address, shouldn't that happen under
> cp_build_addr_expr?  Alternately, drop the address_p parameter and choose
> your path inside warn_for_*_packed_member based on whether rhs is an
> ADDR_EXPR there rather than in the caller.
>

Here is the updated patch.  OK for trunk?

Thanks.


-- 
H.J.

[-- Attachment #2: 0001-C-C-Add-Waddress-of-packed-member.patch --]
[-- Type: text/x-patch, Size: 49029 bytes --]

From b5cecbaabfe0fde7aeb3d3c24d8959853985951c Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 12 Jan 2018 21:12:05 -0800
Subject: [PATCH] C/C++: Add -Waddress-of-packed-member
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When address of packed member of struct or union is taken, it may result
in an unaligned pointer value.  This patch adds -Waddress-of-packed-member
to check alignment at pointer assignment and warn unaligned address as
well as unaligned pointer:

$ cat x.i
struct pair_t
{
  char c;
  int i;
} __attribute__ ((packed));

extern struct pair_t p;
int *addr = &p.i;
$ gcc -O2 -S x.i
x.i:8:13: warning: taking address of packed member of ‘struct pair_t’ may result in an unaligned pointer value [-Waddress-of-packed-member]
8 | int *addr = &p.i;
  |             ^

$ cat c.i
struct B { int i; };
struct C { struct B b; } __attribute__ ((packed));

long* g8 (struct C *p) { return p; }
$ gcc -O2 -S c.i -Wno-incompatible-pointer-types
c.i: In function ‘g8’:
c.i:4:18: warning: converting a packed ‘struct C *’ pointer (alignment 1) to ‘long int *’ (alignment 8) may may result in an unaligned pointer value [-Waddress-of-packed-member]
4 | long* g8 (struct C *p) { return p; }
  |                  ^
c.i:2:8: note: defined here
2 | struct C { struct B b; } __attribute__ ((packed));
  |        ^
$

This warning is enabled by default.  Since read_encoded_value_with_base
in unwind-pe.h has

  union unaligned
    {
      void *ptr;
      unsigned u2 __attribute__ ((mode (HI)));
      unsigned u4 __attribute__ ((mode (SI)));
      unsigned u8 __attribute__ ((mode (DI)));
      signed s2 __attribute__ ((mode (HI)));
      signed s4 __attribute__ ((mode (SI)));
      signed s8 __attribute__ ((mode (DI)));
    } __attribute__((__packed__));
  _Unwind_Internal_Ptr result;

and GCC warns:

gcc/libgcc/unwind-pe.h:210:37: warning: taking address of packed member of 'union unaligned' may result in an unaligned pointer value [-Waddress-of-packed-member]
    result = (_Unwind_Internal_Ptr) u->ptr;
                                    ^
we need to add GCC pragma to ignore -Waddress-of-packed-member.

gcc/c/

	PR c/51628
	* doc/invoke.texi: Document -Wno-address-of-packed-member.

gcc/c-family/

	PR c/51628
	* c-common.h (warn_for_address_or_pointer_of_packed_member): New.
	* c-warn.c (check_address_of_packed_member): New function.
	(check_and_warn_address_of_packed_member): Likewise.
	(warn_for_address_or_pointer_of_packed_member): Likewise.
	* c.opt: Add -Wno-address-of-packed-member.

gcc/c/

	PR c/51628
	* c-typeck.c (convert_for_assignment): Call
	warn_for_address_or_pointer_of_packed_member.

gcc/cp/

	PR c/51628
	* call.c (convert_for_arg_passing): Call
	warn_for_address_or_pointer_of_packed_member.
	* typeck.c (convert_for_assignment): Likewise.

gcc/testsuite/

	PR c/51628
	* c-c++-common/pr51628-1.c: New test.
	* c-c++-common/pr51628-2.c: Likewise.
	* c-c++-common/pr51628-3.c: Likewise.
	* c-c++-common/pr51628-4.c: Likewise.
	* c-c++-common/pr51628-5.c: Likewise.
	* c-c++-common/pr51628-6.c: Likewise.
	* c-c++-common/pr51628-7.c: Likewise.
	* c-c++-common/pr51628-8.c: Likewise.
	* c-c++-common/pr51628-9.c: Likewise.
	* c-c++-common/pr51628-10.c: Likewise.
	* c-c++-common/pr51628-11.c: Likewise.
	* c-c++-common/pr51628-12.c: Likewise.
	* c-c++-common/pr51628-13.c: Likewise.
	* c-c++-common/pr51628-14.c: Likewise.
	* c-c++-common/pr51628-15.c: Likewise.
	* c-c++-common/pr51628-26.c: Likewise.
	* c-c++-common/pr51628-27.c: Likewise.
	* c-c++-common/pr51628-28.c: Likewise.
	* gcc.dg/pr51628-17.c: Likewise.
	* gcc.dg/pr51628-18.c: Likewise.
	* gcc.dg/pr51628-19.c: Likewise.
	* gcc.dg/pr51628-20.c: Likewise.
	* gcc.dg/pr51628-21.c: Likewise.
	* gcc.dg/pr51628-22.c: Likewise.
	* gcc.dg/pr51628-23.c: Likewise.
	* gcc.dg/pr51628-24.c: Likewise.
	* gcc.dg/pr51628-25.c: Likewise.
	* c-c++-common/asan/misalign-1.c: Add
	-Wno-address-of-packed-member.
	* c-c++-common/asan/misalign-2.c: Likewise.
	* c-c++-common/ubsan/align-2.c: Likewise.
	* c-c++-common/ubsan/align-4.c: Likewise.
	* c-c++-common/ubsan/align-6.c: Likewise.
	* c-c++-common/ubsan/align-7.c: Likewise.
	* c-c++-common/ubsan/align-8.c: Likewise.
	* c-c++-common/ubsan/align-10.c: Likewise.
	* g++.dg/ubsan/align-2.C: Likewise.
	* gcc.target/i386/avx512bw-vmovdqu16-2.c: Likewise.
	* gcc.target/i386/avx512f-vmovdqu32-2.c: Likewise.
	* gcc.target/i386/avx512f-vmovdqu64-2.c: Likewise.
	* gcc.target/i386/avx512vl-vmovdqu16-2.c: Likewise.
	* gcc.target/i386/avx512vl-vmovdqu32-2.c: Likewise.
	* gcc.target/i386/avx512vl-vmovdqu64-2.c: Likewise.

libgcc/

	* unwind-pe.h (read_encoded_value_with_base): Add GCC pragma
	to ignore -Waddress-of-packed-member.
---
 gcc/c-family/c-common.h                       |   1 +
 gcc/c-family/c-warn.c                         | 188 ++++++++++++++++++
 gcc/c-family/c.opt                            |   4 +
 gcc/c/c-typeck.c                              |  11 +-
 gcc/cp/call.c                                 |   3 +
 gcc/cp/typeck.c                               |   2 +
 gcc/doc/invoke.texi                           |  11 +-
 gcc/testsuite/c-c++-common/asan/misalign-1.c  |   2 +-
 gcc/testsuite/c-c++-common/asan/misalign-2.c  |   2 +-
 gcc/testsuite/c-c++-common/pr51628-1.c        |  29 +++
 gcc/testsuite/c-c++-common/pr51628-10.c       |  24 +++
 gcc/testsuite/c-c++-common/pr51628-11.c       |  17 ++
 gcc/testsuite/c-c++-common/pr51628-12.c       |  18 ++
 gcc/testsuite/c-c++-common/pr51628-13.c       |   9 +
 gcc/testsuite/c-c++-common/pr51628-14.c       |   9 +
 gcc/testsuite/c-c++-common/pr51628-15.c       |  14 ++
 gcc/testsuite/c-c++-common/pr51628-16.c       |  13 ++
 gcc/testsuite/c-c++-common/pr51628-2.c        |  29 +++
 gcc/testsuite/c-c++-common/pr51628-26.c       |  33 +++
 gcc/testsuite/c-c++-common/pr51628-27.c       |  12 ++
 gcc/testsuite/c-c++-common/pr51628-28.c       |  17 ++
 gcc/testsuite/c-c++-common/pr51628-3.c        |  35 ++++
 gcc/testsuite/c-c++-common/pr51628-4.c        |  35 ++++
 gcc/testsuite/c-c++-common/pr51628-5.c        |  35 ++++
 gcc/testsuite/c-c++-common/pr51628-6.c        |  35 ++++
 gcc/testsuite/c-c++-common/pr51628-7.c        |  29 +++
 gcc/testsuite/c-c++-common/pr51628-8.c        |  36 ++++
 gcc/testsuite/c-c++-common/pr51628-9.c        |  36 ++++
 gcc/testsuite/c-c++-common/ubsan/align-10.c   |   2 +-
 gcc/testsuite/c-c++-common/ubsan/align-2.c    |   2 +-
 gcc/testsuite/c-c++-common/ubsan/align-4.c    |   2 +-
 gcc/testsuite/c-c++-common/ubsan/align-6.c    |   2 +-
 gcc/testsuite/c-c++-common/ubsan/align-7.c    |   2 +-
 gcc/testsuite/c-c++-common/ubsan/align-8.c    |   2 +-
 gcc/testsuite/g++.dg/ubsan/align-2.C          |   2 +-
 gcc/testsuite/gcc.dg/pr51628-17.c             |  10 +
 gcc/testsuite/gcc.dg/pr51628-18.c             |  23 +++
 gcc/testsuite/gcc.dg/pr51628-19.c             |  26 +++
 gcc/testsuite/gcc.dg/pr51628-20.c             |  11 +
 gcc/testsuite/gcc.dg/pr51628-21.c             |  11 +
 gcc/testsuite/gcc.dg/pr51628-22.c             |   9 +
 gcc/testsuite/gcc.dg/pr51628-23.c             |   9 +
 gcc/testsuite/gcc.dg/pr51628-24.c             |  10 +
 gcc/testsuite/gcc.dg/pr51628-25.c             |   9 +
 .../gcc.target/i386/avx512bw-vmovdqu16-2.c    |   2 +-
 .../gcc.target/i386/avx512f-vmovdqu32-2.c     |   2 +-
 .../gcc.target/i386/avx512f-vmovdqu64-2.c     |   2 +-
 .../gcc.target/i386/avx512vl-vmovdqu16-2.c    |   2 +-
 .../gcc.target/i386/avx512vl-vmovdqu32-2.c    |   2 +-
 .../gcc.target/i386/avx512vl-vmovdqu64-2.c    |   2 +-
 libgcc/unwind-pe.h                            |   5 +
 51 files changed, 820 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-1.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-10.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-11.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-12.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-13.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-14.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-15.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-16.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-2.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-26.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-27.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-28.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-3.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-4.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-5.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-6.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-7.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-8.c
 create mode 100644 gcc/testsuite/c-c++-common/pr51628-9.c
 create mode 100644 gcc/testsuite/gcc.dg/pr51628-17.c
 create mode 100644 gcc/testsuite/gcc.dg/pr51628-18.c
 create mode 100644 gcc/testsuite/gcc.dg/pr51628-19.c
 create mode 100644 gcc/testsuite/gcc.dg/pr51628-20.c
 create mode 100644 gcc/testsuite/gcc.dg/pr51628-21.c
 create mode 100644 gcc/testsuite/gcc.dg/pr51628-22.c
 create mode 100644 gcc/testsuite/gcc.dg/pr51628-23.c
 create mode 100644 gcc/testsuite/gcc.dg/pr51628-24.c
 create mode 100644 gcc/testsuite/gcc.dg/pr51628-25.c

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 9e868768d01..0d39004ae3d 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1272,6 +1272,7 @@ extern void c_do_switch_warnings (splay_tree, location_t, tree, tree, bool,
 				  bool);
 extern void warn_for_omitted_condop (location_t, tree);
 extern bool warn_for_restrict (unsigned, tree *, unsigned);
+extern void warn_for_address_or_pointer_of_packed_member (bool, tree, tree);
 
 /* Places where an lvalue, or modifiable lvalue, may be required.
    Used to select diagnostic messages in lvalue_error and
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index a1a7f935964..c14030cd1a7 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -2609,3 +2609,191 @@ warn_for_multistatement_macros (location_t body_loc, location_t next_loc,
     inform (guard_loc, "some parts of macro expansion are not guarded by "
 	    "this %qs clause", guard_tinfo_to_string (keyword));
 }
+
+/* Return struct or union type if the right hand value, RHS, takes the
+   unaligned address of packed member of struct or union when assigning
+   to TYPE.  Otherwise, return NULL_TREE.  */
+
+static tree
+check_address_of_packed_member (tree type, tree rhs)
+{
+  tree base;
+  tree object;
+  tree field;
+
+  if (INDIRECT_REF_P (rhs))
+    rhs = TREE_OPERAND (rhs, 0);
+
+  switch (TREE_CODE (rhs))
+    {
+    case ADDR_EXPR:
+      base = TREE_OPERAND (rhs, 0);
+      while (handled_component_p (base))
+	{
+	  enum tree_code code = TREE_CODE (base);
+	  if (code == COMPONENT_REF)
+	    break;
+	  switch (code)
+	    {
+	    case ARRAY_REF:
+	      base = TREE_OPERAND (base, 0);
+	      break;
+	    default:
+	      /* FIXME: Can it ever happen?  */
+	      gcc_unreachable ();
+	      break;
+	    }
+	}
+      if (TREE_CODE (base) != COMPONENT_REF)
+	return NULL_TREE;
+      object = TREE_OPERAND (base, 0);
+      field = TREE_OPERAND (base, 1);
+      break;
+    case COMPONENT_REF:
+      object = TREE_OPERAND (rhs, 0);
+      field = TREE_OPERAND (rhs, 1);
+      break;
+    default:
+      return NULL_TREE;
+    }
+
+  tree context;
+  unsigned int type_align, record_align;
+
+  /* Check alignment of the data member.  */
+  if (TREE_CODE (field) == FIELD_DECL
+      && (DECL_PACKED (field)
+	  || TYPE_PACKED (TREE_TYPE (field))))
+    {
+      /* Check the expected alignment against the field alignment.  */
+      type_align = TYPE_ALIGN (type);
+      context = DECL_CONTEXT (field);
+      record_align = TYPE_ALIGN (context);
+      if ((record_align % type_align) != 0)
+	return context;
+      tree field_off = byte_position (field);
+      if (!multiple_of_p (TREE_TYPE (field_off), field_off,
+			  size_int (type_align / BITS_PER_UNIT)))
+	return context;
+    }
+
+  /* Check alignment of the object.  */
+  if (TREE_CODE (object) == COMPONENT_REF)
+    {
+      field = TREE_OPERAND (object, 1);
+      if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
+	{
+	  type_align = TYPE_ALIGN (type);
+	  context = DECL_CONTEXT (field);
+	  record_align = TYPE_ALIGN (context);
+	  if ((record_align % type_align) != 0)
+	    return context;
+	}
+    }
+
+  return NULL_TREE;
+}
+
+/* Check and warn if the right hand value, RHS, takes the unaligned
+   address of packed member of struct or union when assigning to TYPE.  */
+
+static void
+check_and_warn_address_of_packed_member (tree type, tree rhs)
+{
+  if (TREE_CODE (rhs) != COND_EXPR)
+    {
+      tree context = check_address_of_packed_member (type, rhs);
+      if (context)
+	{
+	  location_t loc = EXPR_LOC_OR_LOC (rhs, input_location);
+	  warning_at (loc, OPT_Waddress_of_packed_member,
+		      "taking address of packed member of %qT may result "
+		      "in an unaligned pointer value",
+		      context);
+	}
+      return;
+    }
+
+  /* Check the THEN path.  */
+  check_and_warn_address_of_packed_member (type, TREE_OPERAND (rhs, 1));
+
+  /* Check the ELSE path.  */
+  check_and_warn_address_of_packed_member (type, TREE_OPERAND (rhs, 2));
+}
+
+/* Warn if the right hand value, RHS:
+   1. For CONVERT_P == true, is a pointer value which isn't aligned to a
+      pointer type TYPE.
+   2. For CONVERT_P == false, is an address which takes the unaligned
+      address of packed member of struct or union when assigning to TYPE.
+*/
+
+void
+warn_for_address_or_pointer_of_packed_member (bool convert_p, tree type,
+					      tree rhs)
+{
+  if (!warn_address_of_packed_member)
+    return;
+
+  /* Don't warn if we don't assign RHS to a pointer.  */
+  if (!POINTER_TYPE_P (type))
+    return;
+
+  while (TREE_CODE (rhs) == COMPOUND_EXPR)
+    rhs = TREE_OPERAND (rhs, 1);
+
+  if (convert_p)
+    {
+      bool rhspointer_p;
+      tree rhstype;
+
+      /* Check the original type of RHS.  */
+      switch (TREE_CODE (rhs))
+	{
+	case PARM_DECL:
+	case VAR_DECL:
+	  rhstype = TREE_TYPE (rhs);
+	  rhspointer_p = POINTER_TYPE_P (rhstype);
+	  break;
+	case NOP_EXPR:
+	  rhs = TREE_OPERAND (rhs, 0);
+	  if (TREE_CODE (rhs) == ADDR_EXPR)
+	    rhs = TREE_OPERAND (rhs, 0);
+	  rhstype = TREE_TYPE (rhs);
+	  rhspointer_p = TREE_CODE (rhstype) == ARRAY_TYPE;
+	  break;
+	default:
+	  return;
+	}
+
+      if (rhspointer_p && TYPE_PACKED (TREE_TYPE (rhstype)))
+	{
+	  unsigned int type_align = TYPE_ALIGN_UNIT (TREE_TYPE (type));
+	  unsigned int rhs_align = TYPE_ALIGN_UNIT (TREE_TYPE (rhstype));
+	  if ((rhs_align % type_align) != 0)
+	    {
+	      location_t location = EXPR_LOC_OR_LOC (rhs, input_location);
+	      warning_at (location, OPT_Waddress_of_packed_member,
+			  "converting a packed %qT pointer (alignment %d) "
+			  "to %qT (alignment %d) may may result in an "
+			  "unaligned pointer value",
+			  rhstype, rhs_align, type, type_align);
+	      tree decl = TYPE_STUB_DECL (TREE_TYPE (rhstype));
+	      inform (DECL_SOURCE_LOCATION (decl), "defined here");
+	      decl = TYPE_STUB_DECL (TREE_TYPE (type));
+	      if (decl)
+		inform (DECL_SOURCE_LOCATION (decl), "defined here");
+	    }
+	}
+    }
+  else
+    {
+      /* Get the type of the pointer pointing to.  */
+      type = TREE_TYPE (type);
+
+      if (TREE_CODE (rhs) == NOP_EXPR)
+	rhs = TREE_OPERAND (rhs, 0);
+
+      check_and_warn_address_of_packed_member (type, rhs);
+    }
+}
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 43d1d27ac00..3ceee456291 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -616,6 +616,10 @@ Wincompatible-pointer-types
 C ObjC Var(warn_incompatible_pointer_types) Init(1) Warning
 Warn when there is a conversion between pointers that have incompatible types.
 
+Waddress-of-packed-member
+C ObjC C++ ObjC++ Var(warn_address_of_packed_member) Init(1) Warning
+Warn when the address of packed member of struct or union is taken.
+
 Winit-self
 C ObjC C++ ObjC++ Var(warn_init_self) Warning LangEnabledBy(C++ ObjC++,Wall)
 Warn about variables which are initialized to themselves.
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index a5a7da0084c..7ecd38b27d5 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -6541,7 +6541,11 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
     }
 
   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
-    return rhs;
+    {
+      warn_for_address_or_pointer_of_packed_member (false, type,
+						    orig_rhs);
+      return rhs;
+    }
 
   if (coder == VOID_TYPE)
     {
@@ -7036,6 +7040,11 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
 	    }
 	}
 
+      /* If RHS is't an address, check pointer or array of packed
+	 struct or union.  */
+      warn_for_address_or_pointer_of_packed_member
+	(TREE_CODE (orig_rhs) != ADDR_EXPR, type, orig_rhs);
+
       return convert (type, rhs);
     }
   else if (codel == POINTER_TYPE && coder == ARRAY_TYPE)
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index b2ca667c8b4..8d4099d3dea 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7539,6 +7539,9 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
 	}
       maybe_warn_parm_abi (type, cp_expr_loc_or_loc (val, input_location));
     }
+
+  warn_for_address_or_pointer_of_packed_member (false, type, val);
+
   return val;
 }
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index e9932202b46..1400f16a20e 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8926,6 +8926,8 @@ convert_for_assignment (tree type, tree rhs,
       TREE_NO_WARNING (rhs) = 1;
     }
 
+  warn_for_address_or_pointer_of_packed_member (false, type, rhs);
+
   return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
 					    complain, flags);
 }
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 7ef4e7a449b..2815f495ebf 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -278,8 +278,8 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Warning Options,,Options to Request or Suppress Warnings}.
 @gccoptlist{-fsyntax-only  -fmax-errors=@var{n}  -Wpedantic @gol
 -pedantic-errors @gol
--w  -Wextra  -Wall  -Waddress  -Waggregate-return  -Waligned-new @gol
--Walloc-zero  -Walloc-size-larger-than=@var{byte-size}
+-w  -Wextra  -Wall  -Waddress -Waddress-of-packed-member -Waggregate-return @gol
+-Waligned-new -Walloc-zero  -Walloc-size-larger-than=@var{byte-size}
 -Walloca  -Walloca-larger-than=@var{byte-size} @gol
 -Wno-aggressive-loop-optimizations  -Warray-bounds  -Warray-bounds=@var{n} @gol
 -Wno-attributes  -Wbool-compare  -Wbool-operation @gol
@@ -6701,6 +6701,13 @@ behavior and are not portable in C, so they usually indicate that the
 programmer intended to use @code{strcmp}.  This warning is enabled by
 @option{-Wall}.
 
+@item -Waddress-of-packed-member
+@opindex Waddress-of-packed-member
+@opindex Wno-address-of-packed-member
+Warn when the address of packed member of struct or union is taken,
+which usually results in an unaligned pointer value.  This is
+enabled by default.
+
 @item -Wlogical-op
 @opindex Wlogical-op
 @opindex Wno-logical-op
diff --git a/gcc/testsuite/c-c++-common/asan/misalign-1.c b/gcc/testsuite/c-c++-common/asan/misalign-1.c
index 5cd605ac045..ebeb0306706 100644
--- a/gcc/testsuite/c-c++-common/asan/misalign-1.c
+++ b/gcc/testsuite/c-c++-common/asan/misalign-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run { target { ilp32 || lp64 } } } */
-/* { dg-skip-if "" { *-*-* }  { "*" } { "-O2" } } */
+/* { dg-skip-if "" { *-*-* }  { "*" } { "-O2 -Wno-address-of-packed-member" } } */
 /* { dg-additional-options "-fno-omit-frame-pointer" { target *-*-darwin* } } */
 /* { dg-shouldfail "asan" } */
 
diff --git a/gcc/testsuite/c-c++-common/asan/misalign-2.c b/gcc/testsuite/c-c++-common/asan/misalign-2.c
index a6ed49bac05..b27e22d35a8 100644
--- a/gcc/testsuite/c-c++-common/asan/misalign-2.c
+++ b/gcc/testsuite/c-c++-common/asan/misalign-2.c
@@ -1,5 +1,5 @@
 /* { dg-do run { target { ilp32 || lp64 } } } */
-/* { dg-skip-if "" { *-*-* }  { "*" } { "-O2" } } */
+/* { dg-skip-if "" { *-*-* }  { "*" } { "-O2 -Wno-address-of-packed-member" } } */
 /* { dg-additional-options "-fno-omit-frame-pointer" { target *-*-darwin* } } */
 /* { dg-shouldfail "asan" } */
 
diff --git a/gcc/testsuite/c-c++-common/pr51628-1.c b/gcc/testsuite/c-c++-common/pr51628-1.c
new file mode 100644
index 00000000000..5324f9cc964
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-1.c
@@ -0,0 +1,29 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct pair_t
+{
+  int x;
+  int i;
+} __attribute__((packed, aligned (4)));
+
+extern struct pair_t p;
+extern int *x;
+extern void bar (int *);
+
+int *addr = &p.i;
+
+int *
+foo (void)
+{
+  struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
+  int *p0, *p1;
+  p0 = &arr[0].i;
+  bar (p0);
+  p1 = &arr[1].i;
+  bar (p1);
+  bar (&p.i);
+  x = &p.i;
+  return &p.i;
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-10.c b/gcc/testsuite/c-c++-common/pr51628-10.c
new file mode 100644
index 00000000000..085fe1608c4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-10.c
@@ -0,0 +1,24 @@
+/* PR c/51628.  */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O2" } */
+
+struct pair_t
+{
+  char c;
+  __int128_t i;
+} __attribute__ ((packed));
+
+typedef struct unaligned_int128_t_
+{
+  __int128_t value;
+} __attribute__((packed)) unaligned_int128_t;
+
+struct pair_t p = {0, 1};
+unaligned_int128_t *addr = (unaligned_int128_t *) &p.i;
+
+int 
+main() 
+{
+  addr->value = ~(__int128_t)0;
+  return (p.i != 1) ? 0 : 1;
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-11.c b/gcc/testsuite/c-c++-common/pr51628-11.c
new file mode 100644
index 00000000000..7661232ac88
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-11.c
@@ -0,0 +1,17 @@
+/* PR c/51628.  */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O" } */
+
+struct tuple_t
+{
+  char c[12];
+  __int128_t i;
+} __attribute__((packed, aligned (8)));
+
+typedef struct unaligned_int128_t_
+{
+  __int128_t value;
+} __attribute__ ((packed, aligned(4))) unaligned_int128_t;
+
+struct tuple_t p = {{0}, 1};
+unaligned_int128_t *addr = (unaligned_int128_t *)(&p.i);
diff --git a/gcc/testsuite/c-c++-common/pr51628-12.c b/gcc/testsuite/c-c++-common/pr51628-12.c
new file mode 100644
index 00000000000..bc221fa87ef
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-12.c
@@ -0,0 +1,18 @@
+/* PR c/51628.  */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O" } */
+
+struct tuple_t
+{
+  char c[10];
+  __int128_t i;
+} __attribute__((packed, aligned (8)));
+
+typedef struct unaligned_int128_t_
+{
+  __int128_t value;
+} __attribute__ ((packed, aligned(4))) unaligned_int128_t;
+
+struct tuple_t p = {{0}, 1};
+unaligned_int128_t *addr = (unaligned_int128_t *)(&p.i);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/c-c++-common/pr51628-13.c b/gcc/testsuite/c-c++-common/pr51628-13.c
new file mode 100644
index 00000000000..0edd5e7f84d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-13.c
@@ -0,0 +1,9 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct B { int i; };
+struct C { struct B b; } __attribute__ ((packed));
+
+int* h4 (struct C *p) { return &p->b.i; }
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/c-c++-common/pr51628-14.c b/gcc/testsuite/c-c++-common/pr51628-14.c
new file mode 100644
index 00000000000..f50378b8651
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-14.c
@@ -0,0 +1,9 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct A {
+  int i;
+} __attribute__ ((packed));
+
+void* f0 (struct A *p) { return &p->i; }
diff --git a/gcc/testsuite/c-c++-common/pr51628-15.c b/gcc/testsuite/c-c++-common/pr51628-15.c
new file mode 100644
index 00000000000..bcac6d70ad5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-15.c
@@ -0,0 +1,14 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct A {
+  int i;
+} __attribute__ ((packed));
+
+int*
+f (struct A *p, int *q)
+{
+  return q ? q : &p->i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-16.c b/gcc/testsuite/c-c++-common/pr51628-16.c
new file mode 100644
index 00000000000..cd502fe76b8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-16.c
@@ -0,0 +1,13 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct __attribute__ ((packed)) A { int i; };
+struct B {
+  struct A a;
+} b;
+
+int *p = (int*)&b.a.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+int *q = (int*)&b.a;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/c-c++-common/pr51628-2.c b/gcc/testsuite/c-c++-common/pr51628-2.c
new file mode 100644
index 00000000000..abfb84ddd05
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-2.c
@@ -0,0 +1,29 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct pair_t
+{
+  int x;
+  int i;
+} __attribute__((packed, aligned (8)));
+
+extern struct pair_t p;
+extern int *x;
+extern void bar (int *);
+
+int *addr = &p.i;
+
+int *
+foo (void)
+{
+  struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
+  int *p0, *p1;
+  p0 = &arr[0].i;
+  bar (p0);
+  p1 = &arr[1].i;
+  bar (p1);
+  bar (&p.i);
+  x = &p.i;
+  return &p.i;
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-26.c b/gcc/testsuite/c-c++-common/pr51628-26.c
new file mode 100644
index 00000000000..2042379860a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-26.c
@@ -0,0 +1,33 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct A {
+  int i;
+} __attribute__ ((packed));
+
+struct A p = {1};
+int *addr;
+
+int i, j;
+
+void
+foo1 (void)
+{
+  addr = (i = -1, &p.i);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
+
+void
+foo2 (void)
+{
+  addr = (i = -1, j = -2, &p.i);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
+
+void
+foo3 (void)
+{
+  addr = (i = -1, (j = -2, &p.i));
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-27.c b/gcc/testsuite/c-c++-common/pr51628-27.c
new file mode 100644
index 00000000000..9ae1efd7afb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-27.c
@@ -0,0 +1,12 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct A { int i; } __attribute__ ((packed));
+struct B { struct A a; };
+struct C { struct B b; };
+
+extern struct C *p;
+
+int* g8 (void) { return &p->b.a.i; }
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/c-c++-common/pr51628-28.c b/gcc/testsuite/c-c++-common/pr51628-28.c
new file mode 100644
index 00000000000..e8c752d0b12
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-28.c
@@ -0,0 +1,17 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct A { 
+  int i;
+} __attribute__ ((packed));
+
+int *
+foo3 (struct A *p1, int *q1, int *q2, struct A *p2) 
+{
+  return (q1 
+	  ? &p1->i
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+	  : (q2 ? &p2->i : q2));
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-3.c b/gcc/testsuite/c-c++-common/pr51628-3.c
new file mode 100644
index 00000000000..0ea94c845a0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-3.c
@@ -0,0 +1,35 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct pair_t
+{
+  int x;
+  int i;
+} __attribute__((packed, aligned (2)));
+
+extern struct pair_t p;
+extern int *x;
+extern void bar (int *);
+
+int *addr = &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+
+int *
+foo (void)
+{
+  struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
+  int *p0, *p1;
+  p0 = &arr[0].i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p0);
+  p1 = &arr[1].i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p1);
+  bar (&p.i);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  x = &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  return &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-4.c b/gcc/testsuite/c-c++-common/pr51628-4.c
new file mode 100644
index 00000000000..c4c1fb72d6d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-4.c
@@ -0,0 +1,35 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct pair_t
+{
+  int x;
+  int i;
+} __attribute__((packed));
+
+extern struct pair_t p;
+extern int *x;
+extern void bar (int *);
+
+int *addr = &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+
+int *
+foo (void)
+{
+  struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
+  int *p0, *p1;
+  p0 = &arr[0].i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p0);
+  p1 = &arr[1].i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p1);
+  bar (&p.i);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  x = &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  return &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-5.c b/gcc/testsuite/c-c++-common/pr51628-5.c
new file mode 100644
index 00000000000..9d7c309a0ef
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-5.c
@@ -0,0 +1,35 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct pair_t
+{
+  char x;
+  int i;
+} __attribute__((packed));
+
+extern struct pair_t p;
+extern int *x;
+extern void bar (int *);
+
+int *addr = &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+
+int *
+foo (void)
+{
+  struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
+  int *p0, *p1;
+  p0 = &arr[0].i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p0);
+  p1 = &arr[1].i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p1);
+  bar (&p.i);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  x = &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  return &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-6.c b/gcc/testsuite/c-c++-common/pr51628-6.c
new file mode 100644
index 00000000000..52aa07a4cf3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-6.c
@@ -0,0 +1,35 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct pair_t
+{
+  char x;
+  int i;
+} __attribute__((packed, aligned (4)));
+
+extern struct pair_t p;
+extern int *x;
+extern void bar (int *);
+
+int *addr = &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+
+int *
+foo (void)
+{
+  struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
+  int *p0, *p1;
+  p0 = &arr[0].i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p0);
+  p1 = &arr[1].i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p1);
+  bar (&p.i);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  x = &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  return &p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-7.c b/gcc/testsuite/c-c++-common/pr51628-7.c
new file mode 100644
index 00000000000..ae4a681f966
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-7.c
@@ -0,0 +1,29 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct pair_t
+{
+  int x;
+  int i[4];
+} __attribute__((packed, aligned (4)));
+
+extern struct pair_t p;
+extern int *x;
+extern void bar (int *);
+
+int *addr = p.i;
+
+int *
+foo (struct pair_t *p)
+{
+  int *p0, *p1;
+  p0 = p->i;
+  bar (p0);
+  p1 = &p->i[1];
+  bar (p1);
+  bar (p->i);
+  bar (&p->i[2]);
+  x = p->i;
+  return &p->i[3];
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-8.c b/gcc/testsuite/c-c++-common/pr51628-8.c
new file mode 100644
index 00000000000..cc2dae096ae
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-8.c
@@ -0,0 +1,36 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct pair_t
+{
+  char x;
+  int i[4];
+} __attribute__ ((packed, aligned (4)));
+
+extern struct pair_t p;
+extern int *x;
+extern void bar (int *);
+
+int *addr = p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+
+int *
+foo (struct pair_t *p)
+{
+  int *p0, *p1;
+  p0 = p->i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p0);
+  p1 = &p->i[1];
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p1);
+  bar (p->i);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (&p->i[2]);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  x = p->i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  return &p->i[3];
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-9.c b/gcc/testsuite/c-c++-common/pr51628-9.c
new file mode 100644
index 00000000000..0470aa3b93d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr51628-9.c
@@ -0,0 +1,36 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct pair_t
+{
+  int x;
+  int i[4];
+} __attribute__ ((packed));
+
+extern struct pair_t p;
+extern int *x;
+extern void bar (int *);
+
+int *addr = p.i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+
+int *
+foo (struct pair_t *p)
+{
+  int *p0, *p1;
+  p0 = p->i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p0);
+  p1 = &p->i[1];
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (p1);
+  bar (p->i);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  bar (&p->i[2]);
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  x = p->i;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  return &p->i[3];
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/align-10.c b/gcc/testsuite/c-c++-common/ubsan/align-10.c
index 56ae9ebfe30..6210533173c 100644
--- a/gcc/testsuite/c-c++-common/ubsan/align-10.c
+++ b/gcc/testsuite/c-c++-common/ubsan/align-10.c
@@ -1,6 +1,6 @@
 /* Limit this to known non-strict alignment targets.  */
 /* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
-/* { dg-options "-O -fsanitize=alignment -fsanitize-recover=alignment" } */
+/* { dg-options "-O -fsanitize=alignment -fsanitize-recover=alignment -Wno-address-of-packed-member" } */
 
 struct R { int a; } r;
 struct S { struct R a; char b; long long c; short d[10]; };
diff --git a/gcc/testsuite/c-c++-common/ubsan/align-2.c b/gcc/testsuite/c-c++-common/ubsan/align-2.c
index 071de8c202a..336b1c3c907 100644
--- a/gcc/testsuite/c-c++-common/ubsan/align-2.c
+++ b/gcc/testsuite/c-c++-common/ubsan/align-2.c
@@ -1,6 +1,6 @@
 /* Limit this to known non-strict alignment targets.  */
 /* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
-/* { dg-options "-fsanitize=alignment" } */
+/* { dg-options "-fsanitize=alignment -Wno-address-of-packed-member" } */
 
 struct S { int a; char b; long long c; short d[10]; };
 struct T { char a; long long b; };
diff --git a/gcc/testsuite/c-c++-common/ubsan/align-4.c b/gcc/testsuite/c-c++-common/ubsan/align-4.c
index 3252595d330..d5feeee29c6 100644
--- a/gcc/testsuite/c-c++-common/ubsan/align-4.c
+++ b/gcc/testsuite/c-c++-common/ubsan/align-4.c
@@ -1,6 +1,6 @@
 /* Limit this to known non-strict alignment targets.  */
 /* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
-/* { dg-options "-fsanitize=null,alignment" } */
+/* { dg-options "-fsanitize=null,alignment -Wno-address-of-packed-member" } */
 
 #include "align-2.c"
 
diff --git a/gcc/testsuite/c-c++-common/ubsan/align-6.c b/gcc/testsuite/c-c++-common/ubsan/align-6.c
index 3364746fb27..0302b7b8894 100644
--- a/gcc/testsuite/c-c++-common/ubsan/align-6.c
+++ b/gcc/testsuite/c-c++-common/ubsan/align-6.c
@@ -1,6 +1,6 @@
 /* Limit this to known non-strict alignment targets.  */
 /* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
-/* { dg-options "-O -fsanitize=alignment -fsanitize-recover=alignment" } */
+/* { dg-options "-O -fsanitize=alignment -fsanitize-recover=alignment -Wno-address-of-packed-member" } */
 
 struct S { int a; char b; long long c; short d[10]; };
 struct T { char a; long long b; };
diff --git a/gcc/testsuite/c-c++-common/ubsan/align-7.c b/gcc/testsuite/c-c++-common/ubsan/align-7.c
index ec4e87f56d5..dd1e8c91cef 100644
--- a/gcc/testsuite/c-c++-common/ubsan/align-7.c
+++ b/gcc/testsuite/c-c++-common/ubsan/align-7.c
@@ -1,6 +1,6 @@
 /* Limit this to known non-strict alignment targets.  */
 /* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
-/* { dg-options "-O -fsanitize=alignment -fno-sanitize-recover=alignment -fdump-tree-sanopt-details" } */
+/* { dg-options "-O -fsanitize=alignment -fno-sanitize-recover=alignment -Wno-address-of-packed-member -fdump-tree-sanopt-details" } */
 /* { dg-skip-if "" { *-*-* } { "-flto -fno-fat-lto-objects" } } */
 /* { dg-shouldfail "ubsan" } */
 
diff --git a/gcc/testsuite/c-c++-common/ubsan/align-8.c b/gcc/testsuite/c-c++-common/ubsan/align-8.c
index 61c1ceb6682..5fe0e0fe931 100644
--- a/gcc/testsuite/c-c++-common/ubsan/align-8.c
+++ b/gcc/testsuite/c-c++-common/ubsan/align-8.c
@@ -1,6 +1,6 @@
 /* Limit this to known non-strict alignment targets.  */
 /* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
-/* { dg-options "-O -fsanitize=alignment -fsanitize-undefined-trap-on-error -fdump-tree-sanopt-details" } */
+/* { dg-options "-O -fsanitize=alignment -fsanitize-undefined-trap-on-error -Wno-address-of-packed-member -fdump-tree-sanopt-details" } */
 /* { dg-skip-if "" { *-*-* } { "-flto -fno-fat-lto-objects" } } */
 /* { dg-shouldfail "ubsan" } */
 
diff --git a/gcc/testsuite/g++.dg/ubsan/align-2.C b/gcc/testsuite/g++.dg/ubsan/align-2.C
index 3e4f5485d02..c97ede88392 100644
--- a/gcc/testsuite/g++.dg/ubsan/align-2.C
+++ b/gcc/testsuite/g++.dg/ubsan/align-2.C
@@ -1,6 +1,6 @@
 // Limit this to known non-strict alignment targets.
 // { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } }
-// { dg-options "-fsanitize=alignment -Wall -Wno-unused-variable -std=c++11" }
+// { dg-options "-fsanitize=alignment -Wall -Wno-unused-variable -Wno-address-of-packed-member -std=c++11" }
 
 typedef const long int L;
 struct S { long int l; char buf[1 + sizeof (int) + sizeof (L)]; } s;
diff --git a/gcc/testsuite/gcc.dg/pr51628-17.c b/gcc/testsuite/gcc.dg/pr51628-17.c
new file mode 100644
index 00000000000..0be95b2294e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr51628-17.c
@@ -0,0 +1,10 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O -Wno-incompatible-pointer-types" } */
+
+struct A {
+  int i;
+} __attribute__ ((packed));
+
+long* f8 (struct A *p) { return &p->i; }
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-18.c b/gcc/testsuite/gcc.dg/pr51628-18.c
new file mode 100644
index 00000000000..03a04eff75c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr51628-18.c
@@ -0,0 +1,23 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+void foo (int *);
+
+int *
+bar (int n, int k, void *ptr)
+{
+  struct A
+  {
+    int c[k];
+    int x[n];
+  } __attribute__ ((packed, aligned (4)));
+  struct A *p = (struct A *) ptr;
+
+  int *p0, *p1;
+  p0 = p->x;
+  foo (p0);
+  p1 = &p->x[1];
+  foo (p1);
+  return &p->x[1];
+}
diff --git a/gcc/testsuite/gcc.dg/pr51628-19.c b/gcc/testsuite/gcc.dg/pr51628-19.c
new file mode 100644
index 00000000000..7ff03e85cea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr51628-19.c
@@ -0,0 +1,26 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+void foo (int *);
+
+int *
+bar (int n, int k, void *ptr)
+{
+  struct A
+  {
+    char c[k];
+    int x[n];
+  } __attribute__ ((packed));
+  struct A *p = (struct A *) ptr;
+
+  int *p0, *p1;
+  p0 = p->x;
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  foo (p0);
+  p1 = &p->x[1];
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+  foo (p1);
+  return &p->x[1];
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr51628-20.c b/gcc/testsuite/gcc.dg/pr51628-20.c
new file mode 100644
index 00000000000..80888283b73
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr51628-20.c
@@ -0,0 +1,11 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O -Wno-incompatible-pointer-types" } */
+
+struct B { int i; };
+struct C { struct B b; } __attribute__ ((packed));
+
+extern struct C *p;
+
+long* g8 (void) { return p; }
+/* { dg-warning "may may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-21.c b/gcc/testsuite/gcc.dg/pr51628-21.c
new file mode 100644
index 00000000000..3077e72c8d5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr51628-21.c
@@ -0,0 +1,11 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O -Wno-incompatible-pointer-types" } */
+
+struct B { int i; };
+struct C { struct B b; } __attribute__ ((packed));
+
+extern struct C p[];
+
+long* g8 (void) { return p; }
+/* { dg-warning "may may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-22.c b/gcc/testsuite/gcc.dg/pr51628-22.c
new file mode 100644
index 00000000000..1bd5d791639
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr51628-22.c
@@ -0,0 +1,9 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O -Wno-incompatible-pointer-types" } */
+
+struct B { int i; };
+struct C { struct B b; } __attribute__ ((packed));
+
+int* g4 (struct C *p) { return &p->b; }
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-23.c b/gcc/testsuite/gcc.dg/pr51628-23.c
new file mode 100644
index 00000000000..5709be60ac8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr51628-23.c
@@ -0,0 +1,9 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O -Wno-incompatible-pointer-types" } */
+
+struct A {
+  int i;
+} __attribute__ ((packed));
+
+char* f0 (struct A *p) { return &p->i; }
diff --git a/gcc/testsuite/gcc.dg/pr51628-24.c b/gcc/testsuite/gcc.dg/pr51628-24.c
new file mode 100644
index 00000000000..3ad99cd2f16
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr51628-24.c
@@ -0,0 +1,10 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O -Wno-incompatible-pointer-types" } */
+
+struct A {
+  int i;
+} __attribute__ ((packed));
+
+short* f2 (struct A *p) { return &p->i; }
+/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-25.c b/gcc/testsuite/gcc.dg/pr51628-25.c
new file mode 100644
index 00000000000..2fc5c028711
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr51628-25.c
@@ -0,0 +1,9 @@
+/* PR c/51628.  */
+/* { dg-do compile } */
+/* { dg-options "-O -Wno-incompatible-pointer-types" } */
+
+struct B { int i; };
+struct C { struct B b; } __attribute__ ((packed));
+
+long* g8 (struct C *p) { return p; }
+/* { dg-warning "may may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-2.c b/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-2.c
index a61609c40d2..c6e3ebdc507 100644
--- a/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-2.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-O2 -mavx512bw" } */
+/* { dg-options "-O2 -mavx512bw -Wno-address-of-packed-member" } */
 /* { dg-require-effective-target avx512bw } */
 
 #define AVX512BW
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-2.c
index f2edc3dff7b..95a657fc5ff 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-2.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-O2 -mavx512f" } */
+/* { dg-options "-O2 -mavx512f -Wno-address-of-packed-member" } */
 /* { dg-require-effective-target avx512f } */
 
 #define AVX512F
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu64-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu64-2.c
index 14176965ace..954b091d976 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu64-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vmovdqu64-2.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-O2 -mavx512f" } */
+/* { dg-options "-O2 -mavx512f -Wno-address-of-packed-member" } */
 /* { dg-require-effective-target avx512f } */
 
 #define AVX512F
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu16-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu16-2.c
index 45ae83d4552..81465f8d9a0 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu16-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu16-2.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-O2 -mavx512bw -mavx512vl" } */
+/* { dg-options "-O2 -mavx512bw -mavx512vl -Wno-address-of-packed-member" } */
 /* { dg-require-effective-target avx512vl } */
 /* { dg-require-effective-target avx512bw } */
 
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu32-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu32-2.c
index 4b928d0cd42..19390664bd0 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu32-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu32-2.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-O2 -mavx512vl" } */
+/* { dg-options "-O2 -mavx512vl -Wno-address-of-packed-member" } */
 /* { dg-require-effective-target avx512vl } */
 
 #define AVX512VL
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu64-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu64-2.c
index 1863ed3616f..aea0c12a5ff 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu64-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu64-2.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-O2 -mavx512vl" } */
+/* { dg-options "-O2 -mavx512vl -Wno-address-of-packed-member" } */
 /* { dg-require-effective-target avx512vl } */
 
 #define AVX512VL
diff --git a/libgcc/unwind-pe.h b/libgcc/unwind-pe.h
index dd5ae95fc2c..05c2fb4dd50 100644
--- a/libgcc/unwind-pe.h
+++ b/libgcc/unwind-pe.h
@@ -177,6 +177,9 @@ read_sleb128 (const unsigned char *p, _sleb128_t *val)
    The function returns P incremented past the value.  BASE is as given
    by base_of_encoded_value for this encoding in the appropriate context.  */
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
+
 static const unsigned char *
 read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
 			      const unsigned char *p, _Unwind_Ptr *val)
@@ -270,6 +273,8 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
   return p;
 }
 
+#pragma GCC diagnostic pop
+
 #ifndef NO_BASE_OF_ENCODED_VALUE
 
 /* Like read_encoded_value_with_base, but get the base from the context
-- 
2.17.1


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2018-12-20 21:43 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-25 15:47 V4 [PATCH] C/C++: Add -Waddress-of-packed-member H.J. Lu
2018-11-04 15:16 ` PING: " H.J. Lu
2018-11-25 14:38   ` PING^2: " H.J. Lu
2018-12-13 20:50 ` Jason Merrill
2018-12-14  0:09   ` V5 " H.J. Lu
2018-12-14 22:10     ` Jason Merrill
2018-12-14 22:48       ` V6 " H.J. Lu
2018-12-17  9:39         ` Richard Biener
2018-12-17 12:43           ` H.J. Lu
2018-12-17 13:34             ` Richard Biener
2018-12-17 13:53             ` Jason Merrill
2018-12-18 14:11               ` V7 " H.J. Lu
2018-12-18 20:36                 ` Jason Merrill
2018-12-18 21:13                   ` V8 " H.J. Lu
2018-12-18 22:14                     ` Jason Merrill
2018-12-19 14:52                       ` H.J. Lu
2018-12-19 17:36                         ` V9 " H.J. Lu
2018-12-20 19:40                           ` Jason Merrill
2018-12-20 20:07                             ` V10 " H.J. Lu
2018-12-20 21:31                               ` Jason Merrill
2018-12-20 21:47                                 ` H.J. Lu
2018-12-19  3:19                     ` V8 " Sandra Loosemore
2018-12-19 14:53                       ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).