Bug 448743
| Summary: | O2 optimization fails to generate code for statement | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | John Dennis <jdennis> | ||||||||||
| Component: | gcc | Assignee: | Jakub Jelinek <jakub> | ||||||||||
| Status: | CLOSED NOTABUG | QA Contact: | Fedora Extras Quality Assurance <extras-qa> | ||||||||||
| Severity: | high | Docs Contact: | |||||||||||
| Priority: | medium | ||||||||||||
| Version: | 9 | CC: | drepper | ||||||||||
| Target Milestone: | --- | ||||||||||||
| Target Release: | --- | ||||||||||||
| Hardware: | i386 | ||||||||||||
| OS: | Linux | ||||||||||||
| Whiteboard: | |||||||||||||
| Fixed In Version: | Doc Type: | Bug Fix | |||||||||||
| Doc Text: | Story Points: | --- | |||||||||||
| Clone Of: | Environment: | ||||||||||||
| Last Closed: | 2008-05-28 22:30:54 UTC | Type: | --- | ||||||||||
| Regression: | --- | Mount Type: | --- | ||||||||||
| Documentation: | --- | CRM: | |||||||||||
| Verified Versions: | Category: | --- | |||||||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||||||
| Embargoed: | |||||||||||||
| Bug Depends On: | |||||||||||||
| Bug Blocks: | 446864 | ||||||||||||
| Attachments: |
|
||||||||||||
|
Description
John Dennis
2008-05-28 15:19:13 UTC
Created attachment 306938 [details]
original C code
Created attachment 306939 [details]
preprocessed C code
Created attachment 306940 [details]
generated object code
Created attachment 306941 [details]
disassembled machine code with annotations
The problem is an aliasing violation.
struct sockaddr_storage salocal;
...
struct sockaddr_in *sa = (struct sockaddr_in *)&salocal;
...
sa->sin_port = XXX;
...
bind (..., (struct sockaddr *) &salocal, ...);
As sockaddr_storage and sockaddr_in types aren't compatible, the salocal object
has effective type sockaddr_storage (as per ISO C99, 6.5 (6)), the store to
sa->sin_port is invalid. Now, I don't know what is the POSIX intended usage of
struct sockaddr_storage. Either this is supposed to be a valid POSIX use (in
that case we'd need to make struct sockaddr_storage effectively a union of all
known non-AF_UNIX sockaddrs), or it is not and users need to use a union
themselves (union { sockaddr_storage salocal; struct sockaddr_in sa; struct
sockaddr_in6 sa6; }; in this case).
Regardless of whether we try to work around this kind of problem in future, the
fr_socket function is wrong. The invalid casts are forbidden by ISO C. POSIX
does not and cannot guarantee anything about this type of use of sockaddr_storage.
What you should do is this:
union
{
struct sockaddr_storage ss;
struct sockaddr_in s4;
struct sockaddr_in6 s6;
} u;
- replace salocal references with u.ss
- in the IPv4 branch, use u.s4 instead of the local sa variable
- in the IPv6 branch, use u.s6 instead of the local sa variable
|