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()48 int 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