Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

wrong(?) error: member 'rdbuf' found in multiple base classes of different types #6908

Closed Quuxplusone closed 14 years ago

Quuxplusone commented 14 years ago
Bugzilla Link PR6462
Status RESOLVED FIXED
Importance P enhancement
Reported by Albert Zeyer (ich@az2000.de)
Reported on 2010-03-02 10:53:11 -0800
Last modified on 2010-03-06 14:07:10 -0800
Version trunk
Hardware PC All
CC dgregor@apple.com, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments foo2.ii.bz2 (121285 bytes, application/x-bzip2)
Blocks
Blocked by
See also
/Users/az/Programmierung/openlierox/src/common/Process.cpp:96:9: error: member
      'rdbuf' found in multiple base classes of different types
                if(p->rdbuf()) p->rdbuf()->kill();
                      ^
In file included from
/Users/az/Programmierung/openlierox/src/common/Process.cpp:11:
In file included from
/Users/az/Programmierung/openlierox/./include/Process.h:13:
In file included from /usr/include/c++/4.0.0/iostream:43:
In file included from /usr/include/c++/4.0.0/ostream:43:
In file included from /usr/include/c++/4.0.0/ios:49:
/usr/include/c++/4.0.0/bits/basic_ios.h:306:7: note: member found by ambiguous
name
      lookup
      rdbuf() const
      ^
In file included from
/Users/az/Programmierung/openlierox/src/common/Process.cpp:83:
/Users/az/Programmierung/openlierox/./libs/pstreams/pstream.h:315:7: note:
member
      found by ambiguous name lookup
      rdbuf() const;
      ^

I am not exactly sure about this. Maybe the clang error is valid.

The point is that all GCC versions I have tried so far accept it. And I think
ICC too.
Quuxplusone commented 14 years ago

Attached foo2.ii.bz2 (121285 bytes, application/x-bzip2): preproccessed file

Quuxplusone commented 14 years ago

Please try to reduce the test down to something more manageable.

Quuxplusone commented 14 years ago
Reduced test case 1:

#include <iostream>

template<typename T>
class PBuf : public std::basic_streambuf<T> {};

template<typename T>
class Pcommon : virtual public std::basic_ios<T> {
protected:
      typedef PBuf<T>       streambuf_type;

public:
      streambuf_type*
      rdbuf() const { return 0; }
};

template<typename T>
class I : virtual public std::basic_ios<T> {};

template<typename T>
class O : virtual public std::basic_ios<T> {};

template<typename T>
class IO : public I<T>, public O<T> {};

template<typename T>
class P : public IO<T>, public Pcommon<T> {};

void f() { P<char> p; p.rdbuf(); }

---

I will reduce it further.
Quuxplusone commented 14 years ago
More reduced:

template<typename T> struct Buf {};
template<typename T> class PBuf : public Buf<T> {};

template<typename T>
struct BaseIO { Buf<T>* rdbuf() const { return 0; } };

template<typename T>
struct Pcommon : virtual BaseIO<T> { PBuf<T>* rdbuf() const { return 0; } };

template<typename T> struct I : virtual BaseIO<T> {};
template<typename T> struct O : virtual BaseIO<T> {};
template<typename T> struct IO : I<T>, O<T> {};

template<typename T>
struct P : public IO<T>, public Pcommon<T> {};

void f() { P<char> p; p.rdbuf(); }
Quuxplusone commented 14 years ago
And more simple:

struct BaseIO { BaseIO* rdbuf() { return 0; } };
struct Pcommon : virtual BaseIO { int rdbuf() { return 0; } };
struct P : virtual BaseIO, Pcommon {};

void f() { P p; p.rdbuf(); }

---

GCC has no problem to compile this. GCC fails though if I remove one of these
"virtual".
Quuxplusone commented 14 years ago
(In reply to comment #5)
> And more simple:
>
> struct BaseIO { BaseIO* rdbuf() { return 0; } };
> struct Pcommon : virtual BaseIO { int rdbuf() { return 0; } };
> struct P : virtual BaseIO, Pcommon {};
>
> void f() { P p; p.rdbuf(); }
>
> ---
>
> GCC has no problem to compile this. GCC fails though if I remove one of these
> "virtual".

Wonderful, thank you! It appears that we aren't implementing C++
[class.member.lookup]p6, which says:

  When virtual base classes are used, a hidden declaration can be reached along a path through the sub-object lattice that does not pass through the hiding declaration. This is not an ambiguity. The identical use with nonvirtual base classes is an ambiguity; in that case there is no unique instance of the name that hides all the others.
Quuxplusone commented 14 years ago

Fixed in r97640.