LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 19987 - clang-cl: complains 'inheritance model does not match definition'
Summary: clang-cl: complains 'inheritance model does not match definition'
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: -New Bugs (show other bugs)
Version: unspecified
Hardware: PC All
: P normal
Assignee: David Majnemer
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-06-09 17:49 PDT by Jeff Muizelaar
Modified: 2015-06-23 11:19 PDT (History)
5 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jeff Muizelaar 2014-06-09 17:49:31 PDT
Clang fails to compile the following code that succeeds with cl.exe

class A {};
template <class T> class B {
  void (T::*mCallOnResume)();
};
namespace q {
  class C : A, B<C> {
  };
};
Comment 1 Jeff Muizelaar 2014-06-09 17:54:37 PDT
Here's a slightly saner reduction:

class A {};
template <class T> class B {
  void (T::*mCallOnResume)();
};
class C : A, B<C> {
};

C p;
Comment 2 Reid Kleckner 2014-06-09 18:39:02 PDT
As a workaround, you can do this:

class A {};
template <class T> class B {
  void (T::*mCallOnResume)();
};
class __multiple_inheritance C; // workaround
class C : A, B<C> {
};

Our diagnostic is bad, but here's what's happening:

- We parse C's base specifiers
- Instantiate B<C>
- RequireCompleteType on 'void (C::*)()'
- RequireCompleteType on C, lock in the inheritance model, probably as single inheritance, because we haven't set C's base specifiers yet
- Finish C's definition, realize that we assumed C was using single inheritance when it really used multiple inheritance.
Comment 3 Ehsan Akhgari [:ehsan] 2014-06-09 21:38:28 PDT
Thanks a lot for the analysis and workaround, Reid!  I'll try to work with Jeff tomorrow to see how we can apply this workaround to our code.  I have to admit that I don't entirely understand the implications of these MSVC keywords (I just learned about their existence yesterday.)  I assume the workaround won't change how the code will behave when built with cl?
Comment 4 David Majnemer 2014-06-12 17:17:34 PDT
marginally reduced:
template <class T>
class A {
  int T::*x;
};
class B : virtual A<B> {};
Comment 5 David Majnemer 2014-06-13 01:47:40 PDT
Fixed in r210886.
Comment 6 Reid Kleckner 2014-06-18 16:06:21 PDT
I should point out that while we have fixed this in clang, note that sizeof(mCallOnResume) will probably be 16 (1 pointer and 3 ints!) on x86 with both MSVC and Clang.  That's probably larger than you wanted.  The __multiple_inheritance workaround that I gave should make it just 8 (1 pointer and 1 int).
Comment 7 József Mihalicza 2015-06-23 11:02:59 PDT
It seems the fix is not 100% correct.
We are using clang through libTooling, -v gives:
clang version 3.6.0 (branches/release_36 230502) (llvm/branches/release_36 230501).

code (simplified) :
class A : public B<wchar_t>
{
public:
// ...
	typedef bool (A::*C)(const D<wchar_t>&, E&, int, const F&);
// ...
	static C m[];
// ...
};

clang output:
In file included from ...
...
a.h:95:1: error: inheritance model does not match definition
class A : public B<wchar_t>
^
a.h:95:7: note: A defined here
class A : public B<wchar_t>
      ^
1 error generated.
Error while processing ....cpp.
Comment 8 David Majnemer 2015-06-23 11:19:35 PDT
József, I cannot reproduce with what you have posted.  Please provide a complete example.