@@ -118,41 +118,39 @@ bool RTDEF(SameTypeAs)(const Descriptor &a, const Descriptor &b) {
118118}
119119
120120bool RTDEF (ExtendsTypeOf)(const Descriptor &a, const Descriptor &mold) {
121- // The wording of the standard indicates the order in which each case
122- // is checked. If performance becomes an issue, there are less maintainable
123- // versions of this code that would probably execute faster .
121+ // The wording of the standard indicates null or unallocated checks take
122+ // precedence over the extension checks which take precedence over any
123+ // compiler specific behavior .
124124 // F'23 16.9.86 p 5
125125 // If MOLD is unlimited polymorphic and is either a disassociated pointer or
126126 // unallocated allocatable variable, the result is true;
127- if ((mold.IsPointer () || mold.IsAllocatable ()) && !mold.IsAllocated ()) {
128- return true ;
129- } else if ((a.IsPointer () || a.IsAllocatable ()) && !a.IsAllocated ()) {
130- return false ;
131- }
132127 auto aType{a.raw ().type };
133128 auto moldType{mold.raw ().type };
134- if (aType == CFI_type_struct && moldType == CFI_type_struct) {
135- if (const auto *derivedTypeMold{GetDerivedType (mold)}) {
136- // Otherwise if the dynamic type of A or MOLD is extensible, the result is
137- // true if and only if the dynamic type of A is an extension type of the
138- // dynamic type of MOLD.
139- for (const typeInfo::DerivedType *derivedTypeA{GetDerivedType (a)};
140- derivedTypeA; derivedTypeA = derivedTypeA->GetParentType ()) {
141- if (derivedTypeA == derivedTypeMold) {
142- return true ;
143- }
144- }
129+ if ((aType != CFI_type_struct && aType != CFI_type_other) ||
130+ (moldType != CFI_type_struct && moldType != CFI_type_other)) {
131+ if (!mold.IsAllocated ()) {
132+ return true ;
133+ } else if (!a.IsAllocated ()) {
145134 return false ;
135+ } else {
136+ // If either type is intrinsic and not a pointer or allocatable
137+ // then they must match.
138+ return aType == moldType;
146139 }
140+ } else if (const auto *derivedTypeMold{GetDerivedType (mold)}) {
141+ // Otherwise if the dynamic type of A or MOLD is extensible, the result is
142+ // true if and only if the dynamic type of A is an extension type of the
143+ // dynamic type of MOLD.
144+ for (const typeInfo::DerivedType *derivedTypeA{GetDerivedType (a)};
145+ derivedTypeA; derivedTypeA = derivedTypeA->GetParentType ()) {
146+ if (derivedTypeA == derivedTypeMold) {
147+ return true ;
148+ }
149+ }
150+ return false ;
151+ } else {
147152 // MOLD is unlimited polymorphic and unallocated/disassociated.
148- // This might be impossible to reach since the case is now handled
149- // explicitly above.
150153 return true ;
151- } else {
152- // F'23: otherwise, the result is processor dependent.
153- // extension, if types are not extensible, true if they match.
154- return aType != CFI_type_other && moldType != CFI_type_other &&
155- aType == moldType;
156154 }
157155}
158156
0 commit comments