Message ID | 87o79ekwuw.fsf@oldenburg.str.redhat.com |
---|---|
State | New |
Headers | show |
Series | [v4] socket: Use may_alias on sockaddr structs (bug 19622) | expand |
On 5/10/24 2:24 AM, Florian Weimer wrote: > This supports common coding patterns. The GCC C front end before > version 7 rejects the may_alias attribute on a struct definition > if it was not present in a previous forward declaration, so this > attribute can only be conditionally applied. > > This implements the spirit of the change in Austin Group issue 1641. > > Suggested-by: Marek Polacek <polacek@redhat.com> > Suggested-by: Jakub Jelinek <jakub@redhat.com> > Missing the RB from Same James? It hasn't changed substantially since then. Reviewed-by: Carlos O'Donell <carlos@redhat.com> > --- > v2: Mention Austing Group issue 1641. Correct the GCC version range. > The C front end was changed early in the 7 release cycle. > v3: Require the GCC 7 release version based on feedback from Jakub. > v4: Fix typo in commit message. > > bits/socket.h | 4 ++-- > inet/netinet/in.h | 8 +++++--- > misc/sys/cdefs.h | 9 +++++++++ > socket/sys/un.h | 2 +- > sysdeps/mach/hurd/bits/socket.h | 4 ++-- > sysdeps/unix/sysv/linux/bits/socket.h | 4 ++-- > sysdeps/unix/sysv/linux/net/if_packet.h | 2 +- > sysdeps/unix/sysv/linux/netash/ash.h | 2 +- > sysdeps/unix/sysv/linux/neteconet/ec.h | 2 +- > sysdeps/unix/sysv/linux/netiucv/iucv.h | 2 +- > 10 files changed, 25 insertions(+), 14 deletions(-) > > diff --git a/bits/socket.h b/bits/socket.h > index 13de124bac..772074d52a 100644 > --- a/bits/socket.h > +++ b/bits/socket.h > @@ -149,7 +149,7 @@ enum __socket_type > #include <bits/sockaddr.h> > > /* Structure describing a generic socket address. */ > -struct sockaddr > +struct __attribute_struct_may_alias__ sockaddr > { > __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ > char sa_data[14]; /* Address data. */ > @@ -166,7 +166,7 @@ struct sockaddr > #define _SS_PADSIZE \ > (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) > > -struct sockaddr_storage > +struct __attribute_struct_may_alias__ sockaddr_storage > { > __SOCKADDR_COMMON (ss_); /* Address family, etc. */ > char __ss_padding[_SS_PADSIZE]; > diff --git a/inet/netinet/in.h b/inet/netinet/in.h > index fa57b61079..f684be5beb 100644 > --- a/inet/netinet/in.h > +++ b/inet/netinet/in.h > @@ -244,7 +244,7 @@ extern const struct in6_addr in6addr_loopback; /* ::1 */ > > > /* Structure describing an Internet socket address. */ > -struct sockaddr_in > +struct __attribute_struct_may_alias__ sockaddr_in > { > __SOCKADDR_COMMON (sin_); > in_port_t sin_port; /* Port number. */ > @@ -257,9 +257,11 @@ struct sockaddr_in > - sizeof (struct in_addr)]; > }; > > -#if !__USE_KERNEL_IPV6_DEFS > +#if __USE_KERNEL_IPV6_DEFS > +struct __attribute_struct_may_alias__ sockaddr_in6; > +#else > /* Ditto, for IPv6. */ > -struct sockaddr_in6 > +struct __attribute_struct_may_alias__ sockaddr_in6 > { > __SOCKADDR_COMMON (sin6_); > in_port_t sin6_port; /* Transport layer port # */ > diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h > index 2e8279a2c7..ab9620bd0d 100644 > --- a/misc/sys/cdefs.h > +++ b/misc/sys/cdefs.h > @@ -874,4 +874,13 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf > # define __attribute_returns_twice__ /* Ignore. */ > #endif > > +/* Mark struct types as aliasable. Restricted to compilers that > + support forward declarations of structs in the presence of the > + attribute. */ > +#if __GNUC_PREREQ (7, 1) || defined __clang__ OK. Resolve's Jakub's suggestion to use 7.1. > +# define __attribute_struct_may_alias__ __attribute__ ((__may_alias__)) > +#else > +# define __attribute_struct_may_alias__ > +#endif > + > #endif /* sys/cdefs.h */ > diff --git a/socket/sys/un.h b/socket/sys/un.h > index bf03b7d6ce..ff9cbd6efa 100644 > --- a/socket/sys/un.h > +++ b/socket/sys/un.h > @@ -26,7 +26,7 @@ > __BEGIN_DECLS > > /* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket. */ > -struct sockaddr_un > +struct __attribute_struct_may_alias__ sockaddr_un > { > __SOCKADDR_COMMON (sun_); > char sun_path[108]; /* Path name. */ > diff --git a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h > index 3e72f9fa93..b5eeac3731 100644 > --- a/sysdeps/mach/hurd/bits/socket.h > +++ b/sysdeps/mach/hurd/bits/socket.h > @@ -153,7 +153,7 @@ enum __socket_type > #include <bits/sockaddr.h> > > /* Structure describing a generic socket address. */ > -struct sockaddr > +struct __attribute_struct_may_alias__ sockaddr > { > __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ > char sa_data[14]; /* Address data. */ > @@ -170,7 +170,7 @@ struct sockaddr > #define _SS_PADSIZE \ > (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) > > -struct sockaddr_storage > +struct __attribute_struct_may_alias__ sockaddr_storage > { > __SOCKADDR_COMMON (ss_); /* Address family, etc. */ > char __ss_padding[_SS_PADSIZE]; > diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h > index 86444f0018..5ab19a8c08 100644 > --- a/sysdeps/unix/sysv/linux/bits/socket.h > +++ b/sysdeps/unix/sysv/linux/bits/socket.h > @@ -181,7 +181,7 @@ typedef __socklen_t socklen_t; > #include <bits/sockaddr.h> > > /* Structure describing a generic socket address. */ > -struct sockaddr > +struct __attribute_struct_may_alias__ sockaddr > { > __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ > char sa_data[14]; /* Address data. */ > @@ -194,7 +194,7 @@ struct sockaddr > #define _SS_PADSIZE \ > (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) > > -struct sockaddr_storage > +struct __attribute_struct_may_alias__ sockaddr_storage > { > __SOCKADDR_COMMON (ss_); /* Address family, etc. */ > char __ss_padding[_SS_PADSIZE]; > diff --git a/sysdeps/unix/sysv/linux/net/if_packet.h b/sysdeps/unix/sysv/linux/net/if_packet.h > index 9ffb69b508..c17e1c23c5 100644 > --- a/sysdeps/unix/sysv/linux/net/if_packet.h > +++ b/sysdeps/unix/sysv/linux/net/if_packet.h > @@ -26,7 +26,7 @@ > From Linux 2.1 the AF_PACKET interface is preferred and you should > consider using it in place of this one. */ > > -struct sockaddr_pkt > +struct __attribute_struct_may_alias__ sockaddr_pkt > { > __SOCKADDR_COMMON (spkt_); > unsigned char spkt_device[14]; > diff --git a/sysdeps/unix/sysv/linux/netash/ash.h b/sysdeps/unix/sysv/linux/netash/ash.h > index 7d885d17cc..7a6ff50b17 100644 > --- a/sysdeps/unix/sysv/linux/netash/ash.h > +++ b/sysdeps/unix/sysv/linux/netash/ash.h > @@ -22,7 +22,7 @@ > #include <features.h> > #include <bits/sockaddr.h> > > -struct sockaddr_ash > +struct __attribute_struct_may_alias__ sockaddr_ash > { > __SOCKADDR_COMMON (sash_); /* Common data: address family etc. */ > int sash_ifindex; /* Interface to use. */ > diff --git a/sysdeps/unix/sysv/linux/neteconet/ec.h b/sysdeps/unix/sysv/linux/neteconet/ec.h > index b07a107961..f3132f06ff 100644 > --- a/sysdeps/unix/sysv/linux/neteconet/ec.h > +++ b/sysdeps/unix/sysv/linux/neteconet/ec.h > @@ -28,7 +28,7 @@ struct ec_addr > unsigned char net; /* Network number. */ > }; > > -struct sockaddr_ec > +struct __attribute_struct_may_alias__ sockaddr_ec > { > __SOCKADDR_COMMON (sec_); > unsigned char port; /* Port number. */ > diff --git a/sysdeps/unix/sysv/linux/netiucv/iucv.h b/sysdeps/unix/sysv/linux/netiucv/iucv.h > index f5fad81751..27151e8bbe 100644 > --- a/sysdeps/unix/sysv/linux/netiucv/iucv.h > +++ b/sysdeps/unix/sysv/linux/netiucv/iucv.h > @@ -23,7 +23,7 @@ > > __BEGIN_DECLS > > -struct sockaddr_iucv > +struct __attribute_struct_may_alias__ sockaddr_iucv > { > __SOCKADDR_COMMON (siucv_); > unsigned short siucv_port; /* Reserved */ > > base-commit: 143ef68b2aded7c794956beddad495af8c7d3251 >
* Carlos O'Donell: > On 5/10/24 2:24 AM, Florian Weimer wrote: >> This supports common coding patterns. The GCC C front end before >> version 7 rejects the may_alias attribute on a struct definition >> if it was not present in a previous forward declaration, so this >> attribute can only be conditionally applied. >> >> This implements the spirit of the change in Austin Group issue 1641. >> >> Suggested-by: Marek Polacek <polacek@redhat.com> >> Suggested-by: Jakub Jelinek <jakub@redhat.com> >> > > Missing the RB from Sam James? It hasn't changed substantially since then. > > Reviewed-by: Carlos O'Donell <carlos@redhat.com> Sam, does your Reviewed-by: still stand? Thanks, Florian
Florian Weimer <fweimer@redhat.com> writes: > * Carlos O'Donell: > >> On 5/10/24 2:24 AM, Florian Weimer wrote: >>> This supports common coding patterns. The GCC C front end before >>> version 7 rejects the may_alias attribute on a struct definition >>> if it was not present in a previous forward declaration, so this >>> attribute can only be conditionally applied. >>> >>> This implements the spirit of the change in Austin Group issue 1641. >>> >>> Suggested-by: Marek Polacek <polacek@redhat.com> >>> Suggested-by: Jakub Jelinek <jakub@redhat.com> >>> >> >> Missing the RB from Sam James? It hasn't changed substantially since then. >> >> Reviewed-by: Carlos O'Donell <carlos@redhat.com> > > Sam, does your Reviewed-by: still stand? Yes, thanks! thanks, sam
diff --git a/bits/socket.h b/bits/socket.h index 13de124bac..772074d52a 100644 --- a/bits/socket.h +++ b/bits/socket.h @@ -149,7 +149,7 @@ enum __socket_type #include <bits/sockaddr.h> /* Structure describing a generic socket address. */ -struct sockaddr +struct __attribute_struct_may_alias__ sockaddr { __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ char sa_data[14]; /* Address data. */ @@ -166,7 +166,7 @@ struct sockaddr #define _SS_PADSIZE \ (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) -struct sockaddr_storage +struct __attribute_struct_may_alias__ sockaddr_storage { __SOCKADDR_COMMON (ss_); /* Address family, etc. */ char __ss_padding[_SS_PADSIZE]; diff --git a/inet/netinet/in.h b/inet/netinet/in.h index fa57b61079..f684be5beb 100644 --- a/inet/netinet/in.h +++ b/inet/netinet/in.h @@ -244,7 +244,7 @@ extern const struct in6_addr in6addr_loopback; /* ::1 */ /* Structure describing an Internet socket address. */ -struct sockaddr_in +struct __attribute_struct_may_alias__ sockaddr_in { __SOCKADDR_COMMON (sin_); in_port_t sin_port; /* Port number. */ @@ -257,9 +257,11 @@ struct sockaddr_in - sizeof (struct in_addr)]; }; -#if !__USE_KERNEL_IPV6_DEFS +#if __USE_KERNEL_IPV6_DEFS +struct __attribute_struct_may_alias__ sockaddr_in6; +#else /* Ditto, for IPv6. */ -struct sockaddr_in6 +struct __attribute_struct_may_alias__ sockaddr_in6 { __SOCKADDR_COMMON (sin6_); in_port_t sin6_port; /* Transport layer port # */ diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h index 2e8279a2c7..ab9620bd0d 100644 --- a/misc/sys/cdefs.h +++ b/misc/sys/cdefs.h @@ -874,4 +874,13 @@ _Static_assert (0, "IEEE 128-bits long double requires redirection on this platf # define __attribute_returns_twice__ /* Ignore. */ #endif +/* Mark struct types as aliasable. Restricted to compilers that + support forward declarations of structs in the presence of the + attribute. */ +#if __GNUC_PREREQ (7, 1) || defined __clang__ +# define __attribute_struct_may_alias__ __attribute__ ((__may_alias__)) +#else +# define __attribute_struct_may_alias__ +#endif + #endif /* sys/cdefs.h */ diff --git a/socket/sys/un.h b/socket/sys/un.h index bf03b7d6ce..ff9cbd6efa 100644 --- a/socket/sys/un.h +++ b/socket/sys/un.h @@ -26,7 +26,7 @@ __BEGIN_DECLS /* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket. */ -struct sockaddr_un +struct __attribute_struct_may_alias__ sockaddr_un { __SOCKADDR_COMMON (sun_); char sun_path[108]; /* Path name. */ diff --git a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h index 3e72f9fa93..b5eeac3731 100644 --- a/sysdeps/mach/hurd/bits/socket.h +++ b/sysdeps/mach/hurd/bits/socket.h @@ -153,7 +153,7 @@ enum __socket_type #include <bits/sockaddr.h> /* Structure describing a generic socket address. */ -struct sockaddr +struct __attribute_struct_may_alias__ sockaddr { __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ char sa_data[14]; /* Address data. */ @@ -170,7 +170,7 @@ struct sockaddr #define _SS_PADSIZE \ (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) -struct sockaddr_storage +struct __attribute_struct_may_alias__ sockaddr_storage { __SOCKADDR_COMMON (ss_); /* Address family, etc. */ char __ss_padding[_SS_PADSIZE]; diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h index 86444f0018..5ab19a8c08 100644 --- a/sysdeps/unix/sysv/linux/bits/socket.h +++ b/sysdeps/unix/sysv/linux/bits/socket.h @@ -181,7 +181,7 @@ typedef __socklen_t socklen_t; #include <bits/sockaddr.h> /* Structure describing a generic socket address. */ -struct sockaddr +struct __attribute_struct_may_alias__ sockaddr { __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ char sa_data[14]; /* Address data. */ @@ -194,7 +194,7 @@ struct sockaddr #define _SS_PADSIZE \ (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) -struct sockaddr_storage +struct __attribute_struct_may_alias__ sockaddr_storage { __SOCKADDR_COMMON (ss_); /* Address family, etc. */ char __ss_padding[_SS_PADSIZE]; diff --git a/sysdeps/unix/sysv/linux/net/if_packet.h b/sysdeps/unix/sysv/linux/net/if_packet.h index 9ffb69b508..c17e1c23c5 100644 --- a/sysdeps/unix/sysv/linux/net/if_packet.h +++ b/sysdeps/unix/sysv/linux/net/if_packet.h @@ -26,7 +26,7 @@ From Linux 2.1 the AF_PACKET interface is preferred and you should consider using it in place of this one. */ -struct sockaddr_pkt +struct __attribute_struct_may_alias__ sockaddr_pkt { __SOCKADDR_COMMON (spkt_); unsigned char spkt_device[14]; diff --git a/sysdeps/unix/sysv/linux/netash/ash.h b/sysdeps/unix/sysv/linux/netash/ash.h index 7d885d17cc..7a6ff50b17 100644 --- a/sysdeps/unix/sysv/linux/netash/ash.h +++ b/sysdeps/unix/sysv/linux/netash/ash.h @@ -22,7 +22,7 @@ #include <features.h> #include <bits/sockaddr.h> -struct sockaddr_ash +struct __attribute_struct_may_alias__ sockaddr_ash { __SOCKADDR_COMMON (sash_); /* Common data: address family etc. */ int sash_ifindex; /* Interface to use. */ diff --git a/sysdeps/unix/sysv/linux/neteconet/ec.h b/sysdeps/unix/sysv/linux/neteconet/ec.h index b07a107961..f3132f06ff 100644 --- a/sysdeps/unix/sysv/linux/neteconet/ec.h +++ b/sysdeps/unix/sysv/linux/neteconet/ec.h @@ -28,7 +28,7 @@ struct ec_addr unsigned char net; /* Network number. */ }; -struct sockaddr_ec +struct __attribute_struct_may_alias__ sockaddr_ec { __SOCKADDR_COMMON (sec_); unsigned char port; /* Port number. */ diff --git a/sysdeps/unix/sysv/linux/netiucv/iucv.h b/sysdeps/unix/sysv/linux/netiucv/iucv.h index f5fad81751..27151e8bbe 100644 --- a/sysdeps/unix/sysv/linux/netiucv/iucv.h +++ b/sysdeps/unix/sysv/linux/netiucv/iucv.h @@ -23,7 +23,7 @@ __BEGIN_DECLS -struct sockaddr_iucv +struct __attribute_struct_may_alias__ sockaddr_iucv { __SOCKADDR_COMMON (siucv_); unsigned short siucv_port; /* Reserved */