This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Internal compiler error 191


Hi,

We have found a problem in g++ (2.8.1 and 2.95.2) with
the following expression:

   &((type *) 0)->member

where `type' is a class with multiple inheritance from two
classes that have the same base class and `member' is inherited
from the base class.

An example source is attached.

1. First problem (non-virtual base class inheritance):

    A                A

    |                |
    |                |

   B11               B22

    \                /
     \              /

            D


We get here `Internal compiler error 191' for the expression:

         &((D*) 0)->B11::a

2. Second problem (virtual base class inheritance):

            A

         /     \
        /       \

      B1        B2

       \        /
        \      /

           C

We get `invalid reference to NULL ptr, use ptr-to-member instead' for
the expression:

       &((C *) 0)->a
       

We think that in both cases the expression should be possible to evaluate
correctly by the compiler to the relative offset of the class member.
We see though that this can be difficult for the given class hierarchy.

We would like to get a comment if there is a major problem with 
the used expression in the above case or if there is another solution.
We've used successfully the above trick in C to get 
the relative address of a struct member at compile time. 
The expression  doesn't work with g++ for multiple inheritance in C++,
when there is a common base class, for members inherited from that base class.

Best Regards

Piotr Nestorow (Piotr.Nestorow@telelogic.com)
Senior Software Engineer
Development Department
Telelogic AB, Sweden


More background:
---------------
SunOS 5.6, sun4u sparc SUNW,Ultra-1

g++ -v v.cc   -o v
Reading specs from /usr/local/gnu/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/specs
gcc version 2.95.2 19991024 (release)
 /usr/local/gnu/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/cpp -lang-c++ -v -D__GNUC__=2 -D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__sparc__ -D__sun__ -D__unix__ -D__svr4__ -D__SVR4 -D__sparc -D__sun -D__unix -Asystem(unix) -Asystem(svr4) -D__EXCEPTIONS -D__GCC_NEW_VARARGS__ -Acpu(sparc) -Amachine(sparc) v.cc /tmp/ccsrdgpl.ii
GNU CPP version 2.95.2 19991024 (release) (sparc)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/gnu/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/include/g++
 /usr/local/gnu/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/../../../../sparc-sun-solaris2.6/include
 /usr/local/gnu/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/include
 /usr/include
End of search list.
The following default directories have been omitted from the search path:
 /usr/local/include
End of omitted list.
 /usr/local/gnu/lib/gcc-lib/sparc-sun-solaris2.6/2.95.2/cc1plus /tmp/ccsrdgpl.ii -quiet -dumpbase v.cc -version -o /tmp/ccgvVOQy.s
GNU C++ version 2.95.2 19991024 (release) (sparc-sun-solaris2.6) compiled by GNU C version 2.95.2 19991024 (release).


The example:
------------

#include <iostream.h>

class A {
public:
  int a;
};

class B1 : public virtual A {
public:
  int b1;
};

class B2 : public virtual A {
public:
  int b2;
};

class C : public B1, public B2 {
public:
  int c;
};

class B11 : public A {
public:
  int b11;
};

class B22 : public A {
public:
  int b22;
};

class D : public B11, public B22 {
public:
  int d;
};

int main() {
  C* pC = new C;
  D* pD = new D;

  cout << "&((D *) 0)->B11::a == " <<  &((D*) 0)->B11::a << "\n";
  cout << "&((C *) 0)->a == " <<  &((C *) 0)->a << "\n";

  delete pC;
  delete pD;
  return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]