Bug 85871

Summary: g++ 3.2.2 optimization breaks polymorphic references w/ 'typeid' operator
Product: [Retired] Red Hat Raw Hide Reporter: Need Real Name <jfischer_5809>
Component: gcc3Assignee: Jakub Jelinek <jakub>
Status: CLOSED RAWHIDE QA Contact:
Severity: high Docs Contact:
Priority: medium    
Version: 1.0   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: 3.2.2-8 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2003-08-05 16:22:18 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:

Description Need Real Name 2003-03-09 23:02:17 UTC
Description of problem:

If any g++ optimization option is enabled (i.e., -O, -O1, -O2, -O3, or -Os), and
if an lvalue reference of polymorphic class type is specified as the operand of
the C++ 'typeid' operator, the program (at run time) incorrectly specifies the
reference's static type; it should instead specify the referenced object's type.

    class A { public: virtual ~A(){} };
    class B : public A { };
    ...
    void foo() {
        B bobj;
        A& aref = bobj;
        if ( typeid(aref) == typeid(B) ) [1]
            ...
    }

If NO optimization options are specified (or if the -O0 option is specified) on
the g++ command line, then the 'if()' statement's conditional expression [1]
correctly evaluates to 'true' at run time; otherwise it incorrectly evaluates to
'false'.


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

$ g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030217 (Red Hat Linux 8.0 3.2.2-2)

$ g++ --version
g++ (GCC) 3.2.2 20030217 (Red Hat Linux 8.0 3.2.2-2)
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



How reproducible:

Always reproducable.


Steps to Reproduce:
1. Build and execute the following code example as shown below:

<main.cpp>
#include <cstddef>
#include <iostream>
#include <typeinfo>

class A {
public:
    virtual ~A() { }
};

class B : public A { };

int main()
{
    B bobj;
    A& aref = bobj;
    A* aptr = &bobj;

    std::cerr
        << "    A : " << typeid(A).name() << '\n'
        << "    B : " << typeid(B).name() << '\n'
        << " aref : " << typeid(aref).name() << '\n'
        << "*aptr : " << typeid(*aptr).name() << '\n'
        ;

    return EXIT_SUCCESS;
}
</main.cpp>

    
Actual results:

<example.1 -- No optimization>
[bash]$ g++ main.cpp && ./a.out
    A : 1A
    B : 1B
 aref : 1B     // <-- correct
*aptr : 1B
</example.1>

<example.2 -- With optimization>
[bash]$ g++ -O main.cpp && ./a.out
    A : 1A
    B : 1B
 aref : 1A     // <-- wrong
*aptr : 1B
</example.2>

Expected results:

<example.2 -- With optimization>
[bash]$ g++ -O main.cpp && ./a.out
    A : 1A
    B : 1B
 aref : 1B
*aptr : 1B
</example.2>

Additional info: