This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Virtual base class bug introduced in February
- To: egcs-bugs at cygnus dot com
- Subject: Virtual base class bug introduced in February
- From: David Mazieres <dm at reeducation-labor dot lcs dot mit dot edu>
- Date: Mon, 1 Mar 1999 02:29:59 -0500 (EST)
Sometime between January 25 and February 28 a bug was introduced in
the 1.2 (main CVS trunc) version of egcs. The attached code
illustrates the problem. When compiled, it gives this:
% ec++ -v
Reading specs from /usr/local/egcrap/lib/gcc-lib/i386-unknown-openbsd2.4/egcs-2.93.10/specs
gcc version egcs-2.93.10 19990228 (gcc2 ss-980929 experimental)
% ec++ -ansi -Wall -O 0228.C
0228.C: In instantiation of `wrapper<thing>':
0228.C:44: instantiated from here
0228.C:15: warning: direct base `base' inaccessible in `wrapper<thing>' due to ambiguity
0228.C: In method `struct base * friendly::rb<thing>(struct wrapper<thing> *)':
0228.C:32: instantiated from `trouble<thing>::trouble<wrapper<thing>>(wrapper<thing> *)'
0228.C:45: instantiated from here
0228.C:20: type `base' is ambiguous base class for type `wrapper<thing>'
%
There is no ambiguity in the code. A wrapper<thing> class has only
one "base" base class, because the base class is virtual. Thus, the
error message is incorrect. (Also, the word warning seems strange.
If there really were inheritance ambiguity, shouldn't it be an error?
Of course, the code doesn't compile, so I guess this is an error.)
Thanks,
David
===
/* Code written by David Mazieres and placed in the public domain. */
#include <stdio.h>
struct base {
virtual ~base () {}
};
struct thing : public virtual base {
};
template<class T>
struct wrapper : private virtual base, private T {
friend class friendly;
};
struct friendly {
protected:
base *b;
template<class T> base *rb (wrapper<T> *bt) { return bt; }
template<class T> static T *rp (wrapper<T> *bt) { return bt; }
};
template<class T> struct tptr {
T *p;
};
template<class T>
struct trouble : public friendly, public tptr<T> {
template<class U> trouble (U *t) {
#ifndef doesnt_matter
b = friendly::rb (t);
p = friendly::rp (t);
#else
b = rb (t);
p = rp (t);
#endif
}
};
int
main ()
{
wrapper<thing> bt;
trouble<thing> tr (&bt);
fprintf (stderr, "%p\n", tr.p);
return 0;
}