On Tue, Jan 15, 2019 at 7:05 AM Martin Liška <mli...@suse.cz> wrote: > > On 1/15/19 3:19 PM, H.J. Lu wrote: > > On Tue, Jan 15, 2019 at 6:07 AM Martin Liška <mli...@suse.cz> wrote: > >> > >> On 1/14/19 3:14 PM, H.J. Lu wrote: > >>> On Mon, Jan 14, 2019 at 5:53 AM Richard Biener > >>> <richard.guent...@gmail.com> wrote: > >>>> > >>>> On Mon, Jan 14, 2019 at 2:46 PM H.J. Lu <hongjiu...@intel.com> wrote: > >>>>> > >>>>> This patch adds -Waddress-of-packed-member to GCC 9 porting guide. > >>>>> > >>>>> OK to install? > >>>> > >>>> The docs fail to mention what to do when the unaligned pointer is _not_ > >>>> safe to use. That is, how do I fix > >>>> > >>>> struct { char c; int i[4]; } s __attribute__((packed)); > >>>> int foo() > >>>> { > >>>> int *p = s.i; > >>>> return bar (p); > >>>> } > >>>> int bar (int *q) > >>>> { > >>>> return *q; > >>>> } > >>>> > >>>> for the cases where eliding the pointer isn't easily possible? > >>> > >>> You can't have both packed struct and aligned array at the same time. > >>> The only thing I can say is "don't do it". > >>> > >>>> Please also mention the new warning in changes.html > >>>> (it seems to be enabled by default even?). > >>> > >>> I will add a paragraph. > >>> > >>> H.J. > >>>> IIRC the frontends themselves build "bogus" pointer types > >>>> to aligned data from a simple &s.i[1] because the FIELD_DECLs > >>>> types are naturally aligned. > >>>> > >>>> Richard. > >>>> > >>>>> Thanks. > >>>>> > >>>>> H.J. > >>>>> --- > >>>>> Index: gcc-9/porting_to.html > >>>>> =================================================================== > >>>>> RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-9/porting_to.html,v > >>>>> retrieving revision 1.1 > >>>>> diff -u -r1.1 porting_to.html > >>>>> --- gcc-9/porting_to.html 11 Jan 2019 18:21:45 -0000 1.1 > >>>>> +++ gcc-9/porting_to.html 14 Jan 2019 13:46:07 -0000 > >>>>> @@ -56,13 +56,36 @@ > >>>>> } > >>>>> </code></pre> > >>>>> > >>>>> +<h2 id="c/cxx">C/C++ language issues</h2> > >>>>> + > >>>>> +<h3 > >>>>> id="Waddress-of-packed-member"><code>-Waddress-of-packed-member</code> > >>>>> +is enabled by default</h3> > >>>>> + > >>>>> +<p> > >>>>> + When address of packed member of struct or union is taken, it may > >>>>> result > >>>>> + in an unaligned pointer value. A new warning > >>>>> + <code>-Waddress-of-packed-member</code> was added to check alignment > >>>>> at > >>>>> + pointer assignment. It warns both unaligned address and unaligned > >>>>> + pointer. > >>>>> +</p> > >>>>> + > >>>>> +<p> > >>>>> + If the pointer value is safe to use, you can suppress > >>>>> + <code>-Waddress-of-packed-member</code> warnings by using pragmas: > >>>>> +</p> > >>>>> + <pre><code> > >>>>> + #pragma GCC diagnostic push > >>>>> + #pragma GCC diagnostic ignored "-Waddress-of-packed-member" > >>>>> + /* (code for which the warning is to be disabled) */ > >>>>> + #pragma GCC diagnostic pop > >>>>> + </code></pre> > >>>>> + > >>>>> <!-- > >>>>> <h2 id="cxx">C++ language issues</h2> > >>>>> --> > >>>>> > >>>>> <!-- > >>>>> <h2 id="fortran">Fortran language issues</h2> > >>>>> ---> > >>>>> > >>>>> <!-- > >>>>> <h2 id="links">Links</h2> > >>> > >>> > >>> > >> > >> Thanks for working on that. > >> Can we please mention a small demonstration of the problem in porting_to? > >> > >> What about this: > >> $ cat pack.c > >> #include <stddef.h> > >> > >> int main(void) { > >> struct foo { > >> char c; > >> int x; > >> } __attribute__((packed)); > >> struct foo arr[2] = {{'a', 10}, {'b', 20}}; > >> int *p0 = &arr[0].x; > >> int *p1 = &arr[1].x; > >> __builtin_printf("sizeof(struct foo) = %d\n", (int)sizeof(struct > >> foo)); > >> __builtin_printf("offsetof(struct foo, c) = %d\n", (int)offsetof(struct > >> foo, c)); > >> __builtin_printf("offsetof(struct foo, x) = %d\n", (int)offsetof(struct > >> foo, x)); > >> __builtin_printf("arr[0].x = %d\n", arr[0].x); > >> __builtin_printf("arr[1].x = %d\n", arr[1].x); > >> __builtin_printf("&arr = %p\n", arr); > >> __builtin_printf("p0 = %p\n", (void *)p0); > >> __builtin_printf("p1 = %p\n", (void *)p1); > >> __builtin_printf("*p0 = %d\n", *p0); > >> __builtin_printf("*p1 = %d\n", *p1); > >> return 0; > >> } > >> > >> $ gcc pack.c -fsanitize=undefined && ./a.out > >> pack.c: In function ‘main’: > >> pack.c:9:13: warning: taking address of packed member of ‘struct foo’ may > >> result in an unaligned pointer value [-Waddress-of-packed-member] > >> 9 | int *p0 = &arr[0].x; > >> | ^~~~~~~~~ > >> pack.c:10:13: warning: taking address of packed member of ‘struct foo’ may > >> result in an unaligned pointer value [-Waddress-of-packed-member] > >> 10 | int *p1 = &arr[1].x; > >> | ^~~~~~~~~ > >> sizeof(struct foo) = 5 > >> offsetof(struct foo, c) = 0 > >> offsetof(struct foo, x) = 1 > >> arr[0].x = 10 > >> arr[1].x = 20 > >> &arr = 0x7fffffffdc26 > >> p0 = 0x7fffffffdc27 > >> p1 = 0x7fffffffdc2c > >> pack.c:19:3: runtime error: load of misaligned address 0x7fffffffdc27 for > >> type 'int', which requires 4 byte alignment > >> 0x7fffffffdc27: note: pointer points here > >> 00 00 00 61 0a 00 00 00 62 14 00 00 00 2c dc ff ff ff 7f 00 00 27 dc > >> ff ff ff 7f 00 00 80 12 40 > >> ^ > >> *p0 = 10 > >> *p1 = 20 > >> > >> ---end--- > >> > >> It presents the new warning, run-time memory layout dump and also > >> sanitizer error. > >> > >> Thoughts? > > > > This doesn't help port to GCC 9. > > > > > > But it can still go into changes as example of a code > for which the warning is triggered. > > Thoughts?
How about this? -- H.J. --- Index: changes.html =================================================================== RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-9/changes.html,v retrieving revision 1.35 diff -u -p -r1.35 changes.html --- changes.html 15 Jan 2019 13:17:49 -0000 1.35 +++ changes.html 15 Jan 2019 16:24:18 -0000 @@ -84,8 +84,29 @@ a work-in-progress.</p> <ul> <li><code>-Waddress-of-packed-member</code>, enabled by default, warns about an unaligned pointer value from the address of a packed - member of a struct or union. - </li> + member of a struct or union: + <pre><code> +$ cat packed.c +struct packed +{ + char c; + int i; +} __attribute__ ((packed)); + +int * +foo (struct packed *p) +{ + return &p->i; +} +$ gcc -O2 -S packed.c +packed.c: In function ‘foo’: +packed.c:10:10: warning: taking address of packed member of ‘struct packed’ may result in an unaligned pointer value [-Waddress-of-packed-member] + 10 | return &p->i; + | ^~~~~ +$ + </code></pre> + since the pointer returned from function foo may not be an aligned + pointer for int.</li> </ul></li> </ul>