[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#221565: g++-3.3: more detail

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 <graydon@pobox.com>
To: "Zooko O'Whielacronx" <zooko@zooko.com>
Cc: weidai@weidai.com
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 ncm@cantrip.org): 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.


-- 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

Reply to: