On May 30, 2012, at 4:46 AM, r4start wrote:
> On 30/05/2012 07:06, John McCall wrote:
>> Is this the rule used by MSVC? For example, does a vtordisp still get
>> emitted even if a ctor "obviously" doesn't call any virtual functions, like
>> if it's defined in the class definition and obviously empty? Please test
>> both an empty ctor and an empty dtor.
>>
> I think MSVC doesn`t analyze ctor or dtor body.
Excellent. That's very good.
>> Please also add testcases verifying that we do the right thing in
>> further-derived classes that provide ctors. For example:
>> struct A { virtual void foo(); };
>> struct B : virtual A { virtual void foo(); }; // no vtordisp
>> struct Test1 : B { Test1(); };
>> struct Test2 : virtual B { Test2(); };
>> struct Test3 : B { Test3(); virtual void foo(); };
>> struct Test4 : virtual B { Test4(); virtual void foo(); };
>>
> Test3 and Test4 have vtordisps for virtual base A. At now clang(with my
> patch, I test this on my working copy) add vtordisp only in Test4 for B, not
> for A.
> I add new patch. Problem was in undecidedVBases.erase(overriddenBase). In
> Test3 overriddenBase == B but undecidedVBases contains A.
Mmm, I'm not sure about this fix. I suspect that the rule here is that a class
C requires a vtordisp for a virtual base B if:
1) it has a user-defined constructor or destructor and
2) it declares a method which overrides a method declared by that virtual base
or one of its non-virtual bases, directly or no.
This all prompts some more interesting questions which I'd appreciate you
running. Given the following:
struct A { virtual void foo(); };
struct B : A {};
struct C : virtual B { virtual void foo(); };
This tests that the rule applies to "virtual subobjects". I think we know this
already.
struct Test1 : C { Test1(); virtual void foo(); }; // this should need a
vtordisp for B
I'm very suspicious of your "first declaration" test; this should be
sufficient as a counter-example, but the problem is deeper. It's more that we
have to look everywhere in the hierarchy to see what's overridden by the method.
struct Test2a : C { virtual void foo(); };
struct Test2 : Test2 { Test2(); virtual void foo(); }; // this should need a
vtordisp for B
This is just testing whether we can "break up" our class. Basically, should
criterion (2) above be "C declares a method..." or "C's construction vtable
declares a method..."? For correctness, I think the answer *should* be the
latter, but I don't know whether MSVC actually does that, because it requires
the emission of Test3's vtable to create a thunk for Test3a::foo(), which might
be problematic.
struct Test3a : C { virtual void foo(); };
struct Test3 : Test3a { Test3(); };
John.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits