[Bug c++/90186] optimizing options -O1 and -O2 produce different results

2019-04-24 Thread austin.card at torchtechnologies dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90186

--- Comment #2 from austin.card at torchtechnologies dot com ---
(In reply to Richard Biener from comment #1)
> Note that using #pragma pack(1) on struct Ipv4 makes u_short members not
> naturally aligned and thus code like
> 
> void UpdateChecksum()
> {   
> u_long sum(0);
> 
> SetChecksum(0);
> 
> u_short *buf = (u_short*)ip->Payload();
> u_long nwords = ip->PayloadSize() / 2;
> 
> for (unsigned i = 0; i < nwords; ++i)
> {   
> 
> sum += ntohs(*buf++);
> 
> dereferences pointers to u_short that might not be aligned to a 2 byte
> boundary.
> 
> Confirmed though, even when using -fno-inline.  -fno-strict-aliasing fixes
> it.  Possibly the very same issue above - using u_short * to access memory
> with a different dynamic type.  The same happens here:
> 
> buf = (u_short*)
> nwords = 6;
> 
> for (unsigned i = 0; i < nwords; ++i)
> {
> 
> sum += ntohs(*buf++);
> 
> ph is of type PseudoHeader.  You cannot use lvalues of type u_short to
> refer to them.



So if this is an alignment issue, How does the #pragma pack(1) change the
alignment differently between option -O1 and -O2? Also in Udp.h if I uncomment
the dummy function at line 147, then the code produces the same output between
-O1 and -O2. 

I have tried to produce the same result with other compilers:
clang++ -std=c+11 -O2 -o CheckSum main.cpp CheckSum.cpp
clang++ -std=c+11 -O1 -o CheckSum main.cpp CheckSum.cpp
does not have this problem.
And Microsoft VS2017 compiler does not have this problem between Debug and
Release.

Lastly, the code provided is computing the 16-bit checksum of a UDP packet
header contained in an IPv4 network packet. While the comment regarding
alignment of u_short members is in general correct, any misaligned members are
intended by the RFC standards.

[Bug c++/90186] optimizing options -O1 and -O2 produce different results

2019-04-24 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90186

Richard Biener  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #1 from Richard Biener  ---
Note that using #pragma pack(1) on struct Ipv4 makes u_short members not
naturally aligned and thus code like

void UpdateChecksum()
{   
u_long sum(0);

SetChecksum(0);

u_short *buf = (u_short*)ip->Payload();
u_long nwords = ip->PayloadSize() / 2;

for (unsigned i = 0; i < nwords; ++i)
{   

sum += ntohs(*buf++);

dereferences pointers to u_short that might not be aligned to a 2 byte
boundary.

Confirmed though, even when using -fno-inline.  -fno-strict-aliasing fixes
it.  Possibly the very same issue above - using u_short * to access memory
with a different dynamic type.  The same happens here:

buf = (u_short*)
nwords = 6;

for (unsigned i = 0; i < nwords; ++i)
{

sum += ntohs(*buf++);

ph is of type PseudoHeader.  You cannot use lvalues of type u_short to
refer to them.