On 1/15/19 5:25 PM, H.J. Lu wrote: > 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? >
I would then at least mention what's the natural alignment of type that's reported in the warning. Martin