From 54b68f11c18971d1371d5bb5bde7b0c1d3e6ee7b Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 12 Jan 2018 21:12:05 -0800 Subject: 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 warn it: $ 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: initialization of 'int *' from address of packed member of 'struct pair_t' may result in an unaligned pointer value [-Waddress-of-packed-member] int *addr = &p.i; ^ $ This warning is enabled by default. 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_of_packed_member): New. * c-warn.c (warn_for_address_of_packed_member): New function. * c.opt: Add -Wno-address-of-packed-member. gcc/c/ PR c/51628 * c-typeck.c (convert_for_assignment): Call warn_for_address_of_packed_member. Issue an warning if address of packed member is taken. gcc/cp/ PR c/51628 * call.c (convert_for_arg_passing): Call warn_for_address_of_packed_member. Issue an warning if address of packed member is taken. * typeck.c (convert_for_assignment): Likewise. gcc/testsuite/ PR c/51628 * c-c++-common/pr51628-1.c: New tests. * c-c++-common/pr51628-10.c: Likewise. * 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. * gcc.dg/pr51628-10.c: Likewise. * gcc.dg/pr51628-11.c: Likewise. * c-c++-common/ubsan/align-10.c: Add -Wno-address-of-packed-member. * 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. * 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. --- gcc/testsuite/c-c++-common/pr51628-1.c | 29 +++++++++++++++++++++++ gcc/testsuite/c-c++-common/pr51628-10.c | 24 +++++++++++++++++++ gcc/testsuite/c-c++-common/pr51628-2.c | 29 +++++++++++++++++++++++ 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 +- 16 files changed, 329 insertions(+), 6 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-2.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 (limited to 'gcc/testsuite/c-c++-common') 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-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-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" } */ -- cgit v1.2.1