Package: g++-3.3 Version: 1:3.3.3-6 Severity: normal Followup-For: Bug #221565
Sorry for the delay in providing this information. This information is all from Graydon Hoare, and I'm just relaying it. Date: Tue, 09 Mar 2004 12:29:44 -0500 From: graydon hoare <[EMAIL PROTECTED]> To: "Zooko O'Whielacronx" <[EMAIL PROTECTED]> Cc: [EMAIL PROTECTED] Subject: Re: Debian's gcc still miscompiles Crypto++ when -O2 ? Zooko O'Whielacronx wrote: > Graydon, Wei: > > http://www.mail-archive.com/cryptopp-list@eskimo.com/msg01449.html > > <sigh> > > I reported it to Debian, but then I never got around to writing a nice little > test case for them. If Crypto++ 5.1 exercises the bug in its self-test, then > maybe Debian would accept that as a test case. I have actually spent some time whittling it down. here is what I found (with help from [EMAIL PROTECTED]): the problem file is integer.cpp, and the problem with it is due to aliasing rules. strict "type based alias analysis" (on by default with -O2) means that accessing members of a union via a pointer to a member type, rather than via the union itself, can confuse the compiler into thinking that two accesses have different (non-aliasing) physical locations, because they have a different type, when in fact you may be hitting the same region through two different pointers. integer.cpp does a lot of this sort of thing with the word/dword union. the "normal" solution to this is to build the offending code with -fno-strict-aliasing. I don't know precisely why RH's compiler doesn't have this need, but I'd guess it's in one of the many patches applied before shipping. apple's build of 3.3 actually ships with strict aliasing turned off on -O2 altogether; too much trouble. I find a few RH patches which diddle around with the alias analysis code, but nothing is sticking out at me. I am not really good friends with the C++ frontend yet. another solution involves a __may_alias__ attribute stuck on the word/dword union in cryptopp itself, like so: --- cryptopp/config.h +++ cryptopp/config.h @@ -125,8 +125,8 @@ // dword should be twice as big as word #if (defined(__GNUC__) && !defined(__alpha)) || defined(__MWERKS__) - typedef unsigned long word; - typedef unsigned long long dword; + typedef unsigned long __attribute__((__may_alias__)) word; + typedef unsigned long long __attribute__((__may_alias__)) dword; #elif defined(_MSC_VER) || defined(__BCPLUSPLUS__) typedef unsigned __int32 word; typedef unsigned __int64 dword; that seems to fix it, for me. of course, such a draconian fix might well hurt performance, and it only works with gcc versions >= 3.3, I think, so probably some more ifdef'ing is necessary in there, and maybe pushing the attribute down to the union members themselves. -graydon -- System Information: Debian Release: testing/unstable APT prefers testing APT policy: (900, 'testing') Architecture: i386 (i686) Kernel: Linux 2.4.25 Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 Versions of packages g++-3.3 depends on: ii gcc-3.3 1:3.3.3-6 The GNU C compiler ii gcc-3.3-base 1:3.3.3-6 The GNU Compiler Collection (base hi libc6 2.3.2.ds1-11 GNU C Library: Shared libraries an ii libstdc++5-3.3-dev 1:3.3.3-6 The GNU Standard C++ Library v3 (d