This service will be undergoing maintenance at 00:00 UTC, 2016-09-28. It is expected to last about 1 hours
Bug 136120 - g++ generates incorrect code for aliased pointer assignments in c++
g++ generates incorrect code for aliased pointer assignments in c++
Status: CLOSED NOTABUG
Product: Fedora
Classification: Fedora
Component: gcc (Show other bugs)
3
i686 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2004-10-17 22:09 EDT by Dr Thomas Conway
Modified: 2007-11-30 17:10 EST (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2004-10-18 04:44:16 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)

  None (edit)
Description Dr Thomas Conway 2004-10-17 22:09:14 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3)
Gecko/20040929

Description of problem:
The following program should produce no output.

When compiled:
    g++ -O1 -o bug bug.cc
it behaves correctly.
When compiled:
    g++ -O1 -fstrict-aliasing -fschedule-insns -o bug bug.cc
or
    g++ -O2 -o bug bug.cc
it produces output.

See the comments in the text of the program for more detail.

$ cat bug.cc
#include <iostream>

struct Key
{
    long key;
    long ordering;

    Key() : key(0), ordering(0) {}
};

int
main(int argc, const char* argv[])
{
    long* ordering = new long[100];

    for (int i = 0; i < 100; ++i)
    {
        ordering[i] = i;
    }

    Key* keys = new Key[100];

    // We *reuse* the ordering array as an array of key pointers.
    Key** perm = reinterpret_cast<Key**>(ordering);

    int base = 0;
    for (int k = 0; k < 1; ++k)
    {
        int n = &ordering[100] - &ordering[0];
        for (int i = 0; i < 100; ++i)
        {
            // XXX When compiled with -O2 or
            // -O1 -fstrict-aliasing -fschedule-insns
            // these two statements appear to be reversed!

            // copy the ordering value into the key
            keys[i + base].ordering = ordering[i];
            // copy the address of the key over the ordering value
            perm[i] = &keys[i + base];
        }
        base += n;
    }

    // Check the ordering values.
    // If the compiler gets it right, there should be no output.
    for (int i = 0; i < 100; ++i)
    {
        if (keys[i].ordering != i)
        {
            std::cerr << "keys[" << i << "].ordering == " <<
keys[i].ordering
                      << std::endl;
        }
    }

    delete [] keys;
    delete [] ordering;

    return 0;
}



Version-Release number of selected component (if applicable):
gcc-3.4.2-2

How reproducible:
Always

Steps to Reproduce:
see above.

Additional info:

this bug, like all code generator bugs is worrying because it can
be hard to know if you're triggering it or not. Your program *might*
work. Fortunately it seems you can work around it by adding
-fno-strict-aliasing to the compiler arguments, though this does
result in the loss of some legitimate optimization of course.
Comment 1 Jakub Jelinek 2004-10-18 04:44:16 EDT
The reinterpret_cast is exactly what you shouldn't be doing, see
info gcc on -fstrict-aliasing, at least IMHO.

ISO C++, 3.10#15 says:
If a program attempts to access the stored value of an object through an
lvalue of other than one of the following types the behaviour is undefined:
- the dynamic type of the object,
- a cv-qualified version of the dynamic type of the object,
- a type that is the signed or unsigned type corresponding to the dynamic
  type of the object,
- a type that is the signed or unsigned type corresponding to a cv-qualified
  version of the dynamic type of the object,
- an aggregate or union type that includes one of the aforementioned types
  among its members (including, recursively, a member of a subaggregate or
  contained union)
- a type that is a (possibly cv-qualified) base class type of the dynamic
  type of the object,
- a char or unsigned char type

The dynamic type of the object keys[i] is Key, and long certainly is not
one of the types mentioned above, so IMHO what you are seeing is perfectly
fine behaviour.

Note You need to log in before you can comment on or make changes to this bug.