1 struct OtherBase { 2 // Allow checking actual type from the test by giving 3 // this class and the subclass unique values here. valueOtherBase4 virtual const char *value() { return "base"; } 5 }; 6 struct OtherDerived : public OtherBase { valueOtherDerived7 const char *value() override { return "derived"; } 8 }; 9 10 // Those have to be globals as they would be completed if they 11 // are members (which would make this test always pass). 12 OtherBase other_base; 13 OtherDerived other_derived; 14 15 struct Base { 16 // Function with covariant return type that is same class. getPtrBase17 virtual Base* getPtr() { return this; } getRefBase18 virtual Base& getRef() { return *this; } 19 // Function with covariant return type that is a different class. getOtherPtrBase20 virtual OtherBase* getOtherPtr() { return &other_base; } getOtherRefBase21 virtual OtherBase& getOtherRef() { return other_base; } 22 }; 23 24 struct Derived : public Base { getPtrDerived25 Derived* getPtr() override { return this; } getRefDerived26 Derived& getRef() override { return *this; } getOtherPtrDerived27 OtherDerived* getOtherPtr() override { return &other_derived; } getOtherRefDerived28 OtherDerived& getOtherRef() override { return other_derived; } 29 }; 30 31 // A regression test for a class with at least two members containing a 32 // covariant function, which is referenced through another covariant function. 33 struct BaseWithMembers { 34 int a = 42; 35 int b = 47; getBaseWithMembers36 virtual BaseWithMembers *get() { return this; } 37 }; 38 struct DerivedWithMembers: BaseWithMembers { getDerivedWithMembers39 DerivedWithMembers *get() override { return this; } 40 }; 41 struct ReferencingBase { getOtherReferencingBase42 virtual BaseWithMembers *getOther() { return new BaseWithMembers(); } 43 }; 44 struct ReferencingDerived: ReferencingBase { getOtherReferencingDerived45 DerivedWithMembers *getOther() { return new DerivedWithMembers(); } 46 }; 47 main()48int main() { 49 Derived derived; 50 Base base; 51 Base *base_ptr_to_derived = &derived; 52 (void)base_ptr_to_derived->getPtr(); 53 (void)base_ptr_to_derived->getRef(); 54 (void)base_ptr_to_derived->getOtherPtr(); 55 (void)base_ptr_to_derived->getOtherRef(); 56 57 ReferencingDerived referencing_derived; 58 return 0; // break here 59 } 60