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.


-- 
H.J.

Reply via email to