Skip to content

Commit 2b7e3f6

Browse files
authored
[flang] Unify derived types in distinct module files (#146759)
When using -fhermetic-module-files it's possible for a derived type to have multiple distinct definition sites that are being compared for being the same type, as in argument association. Accept them as being the same type so long as they have the same names, the same module names, and identical definitions.
1 parent dd3214d commit 2b7e3f6

File tree

2 files changed

+57
-16
lines changed

2 files changed

+57
-16
lines changed

flang/lib/Evaluate/type.cpp

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -299,13 +299,18 @@ static bool AreSameDerivedType(const semantics::DerivedTypeSpec &,
299299

300300
// F2023 7.5.3.2
301301
static bool AreSameComponent(const semantics::Symbol &x,
302-
const semantics::Symbol &y, bool ignoreSequence,
302+
const semantics::Symbol &y, bool ignoreSequence, bool sameModuleName,
303303
SetOfDerivedTypePairs &inProgress) {
304304
if (x.attrs() != y.attrs()) {
305305
return false;
306306
}
307-
if (x.attrs().test(semantics::Attr::PRIVATE)) {
308-
return false;
307+
if (x.attrs().test(semantics::Attr::PRIVATE) ||
308+
y.attrs().test(semantics::Attr::PRIVATE)) {
309+
if (!sameModuleName ||
310+
x.attrs().test(semantics::Attr::PRIVATE) !=
311+
y.attrs().test(semantics::Attr::PRIVATE)) {
312+
return false;
313+
}
309314
}
310315
if (x.size() && y.size()) {
311316
if (x.offset() != y.offset() || x.size() != y.size()) {
@@ -482,9 +487,20 @@ static bool AreSameDerivedType(const semantics::DerivedTypeSpec &x,
482487
ySymbol.attrs().test(semantics::Attr::BIND_C)) {
483488
return false;
484489
}
485-
if (!ignoreSequence && !(xDetails.sequence() && yDetails.sequence()) &&
486-
!(xSymbol.attrs().test(semantics::Attr::BIND_C) &&
487-
ySymbol.attrs().test(semantics::Attr::BIND_C))) {
490+
bool sameModuleName{false};
491+
const semantics::Scope &xOwner{xSymbol.owner()};
492+
const semantics::Scope &yOwner{ySymbol.owner()};
493+
if (xOwner.IsModule() && yOwner.IsModule()) {
494+
if (auto xModuleName{xOwner.GetName()}) {
495+
if (auto yModuleName{yOwner.GetName()}) {
496+
if (*xModuleName == *yModuleName) {
497+
sameModuleName = true;
498+
}
499+
}
500+
}
501+
}
502+
if (!sameModuleName && !ignoreSequence && !xDetails.sequence() &&
503+
!xSymbol.attrs().test(semantics::Attr::BIND_C)) {
488504
// PGI does not enforce this requirement; all other Fortran
489505
// compilers do with a hard error when violations are caught.
490506
return false;
@@ -502,9 +518,10 @@ static bool AreSameDerivedType(const semantics::DerivedTypeSpec &x,
502518
const auto xLookup{xSymbol.scope()->find(*xComponentName)};
503519
const auto yLookup{ySymbol.scope()->find(*yComponentName)};
504520
if (xLookup == xSymbol.scope()->end() ||
505-
yLookup == ySymbol.scope()->end() ||
506-
!AreSameComponent(
507-
*xLookup->second, *yLookup->second, ignoreSequence, inProgress)) {
521+
yLookup == ySymbol.scope()->end()) {
522+
return false;
523+
} else if (!AreSameComponent(*xLookup->second, *yLookup->second,
524+
ignoreSequence, sameModuleName, inProgress)) {
508525
return false;
509526
}
510527
}
@@ -576,17 +593,15 @@ static bool AreCompatibleTypes(const DynamicType &x, const DynamicType &y,
576593
const auto yLen{y.knownLength()};
577594
return x.kind() == y.kind() &&
578595
(ignoreLengths || !xLen || !yLen || *xLen == *yLen);
579-
} else if (x.category() != TypeCategory::Derived) {
580-
if (x.IsTypelessIntrinsicArgument()) {
581-
return y.IsTypelessIntrinsicArgument();
582-
} else {
583-
return !y.IsTypelessIntrinsicArgument() && x.kind() == y.kind();
584-
}
585-
} else {
596+
} else if (x.category() == TypeCategory::Derived) {
586597
const auto *xdt{GetDerivedTypeSpec(x)};
587598
const auto *ydt{GetDerivedTypeSpec(y)};
588599
return AreCompatibleDerivedTypes(
589600
xdt, ydt, x.IsPolymorphic(), ignoreTypeParameterValues, false);
601+
} else if (x.IsTypelessIntrinsicArgument()) {
602+
return y.IsTypelessIntrinsicArgument();
603+
} else {
604+
return !y.IsTypelessIntrinsicArgument() && x.kind() == y.kind();
590605
}
591606
}
592607

flang/test/Semantics/bug1092.F90

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
!RUN: rm -rf %t && mkdir -p %t
2+
!RUN: %flang_fc1 -DWHICH=1 -fsyntax-only -J%t %s
3+
!RUN: %flang_fc1 -DWHICH=2 -fsyntax-only -fhermetic-module-files -I%t -J%t %s
4+
!RUN: %flang_fc1 -fsyntax-only -I%t %s 2>&1 | FileCheck --allow-empty %s
5+
!CHECK-NOT: error:
6+
7+
#if WHICH == 1
8+
module bug1092a
9+
type t
10+
end type
11+
contains
12+
subroutine subr(x)
13+
type(t) x
14+
end
15+
end
16+
#elif WHICH == 2
17+
module bug1092b
18+
use bug1092a, only: subr
19+
end
20+
#else
21+
use bug1092a, only: t
22+
use bug1092b, only: subr
23+
type(t) x
24+
call subr(x)
25+
end
26+
#endif

0 commit comments

Comments
 (0)