C/C++: Add -Waddress-of-packed-member
authorH.J. Lu <hongjiu.lu@intel.com>
Thu, 20 Dec 2018 21:41:48 +0000 (21:41 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Thu, 20 Dec 2018 21:41:48 +0000 (13:41 -0800)
commitda77eace90fd99b38cd89ce281033d86ebfda434
tree4db570f813ef0aad9843f5cfef17ee5b016fd147
parent11e07fa4327e52771134fa41e3f32d800097e408
C/C++: Add -Waddress-of-packed-member

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/

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_alignment_of_packed_member): New function.
(check_address_of_packed_member): Likewise.
(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.
* c-c++-common/pr51628-29.c: Likewise.
* c-c++-common/pr51628-30.c: Likewise.
* c-c++-common/pr51628-31.c: Likewise.
* c-c++-common/pr51628-32.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.

From-SVN: r267313
61 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.h
gcc/c-family/c-warn.c
gcc/c-family/c.opt
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/typeck.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/asan/misalign-1.c
gcc/testsuite/c-c++-common/asan/misalign-2.c
gcc/testsuite/c-c++-common/pr51628-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-10.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-11.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-12.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-13.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-14.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-15.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-16.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-26.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-27.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-28.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-29.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-3.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-30.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-31.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-32.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-4.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-5.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-6.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-7.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-8.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-9.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/ubsan/align-10.c
gcc/testsuite/c-c++-common/ubsan/align-2.c
gcc/testsuite/c-c++-common/ubsan/align-4.c
gcc/testsuite/c-c++-common/ubsan/align-6.c
gcc/testsuite/c-c++-common/ubsan/align-7.c
gcc/testsuite/c-c++-common/ubsan/align-8.c
gcc/testsuite/g++.dg/ubsan/align-2.C
gcc/testsuite/gcc.dg/pr51628-17.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-18.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-19.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-20.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-21.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-22.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-23.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-24.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-25.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-2.c
gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-2.c
gcc/testsuite/gcc.target/i386/avx512f-vmovdqu64-2.c
gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu16-2.c
gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu32-2.c
gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu64-2.c
libgcc/ChangeLog
libgcc/unwind-pe.h