@@ -2548,9 +2548,11 @@ void ScopeHandler::PopScope() {
25482548 ConvertToObjectEntity (*pair.second );
25492549 }
25502550 funcResultStack_.Pop ();
2551- // If popping back into a global scope, pop back to the main global scope.
2552- SetScope (currScope_->parent ().IsGlobal () ? context ().globalScope ()
2553- : currScope_->parent ());
2551+ // If popping back into a global scope, pop back to the top scope.
2552+ Scope *hermetic{context ().currentHermeticModuleFileScope ()};
2553+ SetScope (currScope_->parent ().IsGlobal ()
2554+ ? (hermetic ? *hermetic : context ().globalScope ())
2555+ : currScope_->parent ());
25542556}
25552557void ScopeHandler::SetScope (Scope &scope) {
25562558 currScope_ = &scope;
@@ -3179,6 +3181,111 @@ static bool ConvertToUseError(
31793181 }
31803182}
31813183
3184+ // Two ultimate symbols are distinct, but they have the same name and come
3185+ // from modules with the same name. At link time, their mangled names
3186+ // would conflict, so they had better resolve to the same definition.
3187+ // Check whether the two ultimate symbols have compatible definitions.
3188+ // Returns true if no further processing is required in DoAddUse().
3189+ static bool CheckCompatibleDistinctUltimates (SemanticsContext &context,
3190+ SourceName location, SourceName localName, const Symbol &localSymbol,
3191+ const Symbol &localUltimate, const Symbol &useUltimate) {
3192+ bool bad{false };
3193+ if (localUltimate.has <GenericDetails>()) {
3194+ if (useUltimate.has <GenericDetails>() ||
3195+ useUltimate.has <SubprogramDetails>() ||
3196+ useUltimate.has <DerivedTypeDetails>()) {
3197+ return false ; // can try to merge them
3198+ } else {
3199+ bad = true ;
3200+ }
3201+ } else if (useUltimate.has <GenericDetails>()) {
3202+ if (localUltimate.has <SubprogramDetails>() ||
3203+ localUltimate.has <DerivedTypeDetails>()) {
3204+ return false ; // can try to merge them
3205+ } else {
3206+ bad = true ;
3207+ }
3208+ } else if (localUltimate.has <SubprogramDetails>()) {
3209+ if (useUltimate.has <SubprogramDetails>()) {
3210+ auto localCharacteristics{
3211+ evaluate::characteristics::Procedure::Characterize (
3212+ localUltimate, context.foldingContext ())};
3213+ auto useCharacteristics{
3214+ evaluate::characteristics::Procedure::Characterize (
3215+ useUltimate, context.foldingContext ())};
3216+ if ((localCharacteristics &&
3217+ (!useCharacteristics ||
3218+ *localCharacteristics != *useCharacteristics)) ||
3219+ (!localCharacteristics && useCharacteristics)) {
3220+ bad = true ;
3221+ }
3222+ } else {
3223+ bad = true ;
3224+ }
3225+ } else if (useUltimate.has <SubprogramDetails>()) {
3226+ bad = true ;
3227+ } else if (const auto *localObject{
3228+ localUltimate.detailsIf <ObjectEntityDetails>()}) {
3229+ if (const auto *useObject{useUltimate.detailsIf <ObjectEntityDetails>()}) {
3230+ auto localType{evaluate::DynamicType::From (localUltimate)};
3231+ auto useType{evaluate::DynamicType::From (useUltimate)};
3232+ if (localUltimate.size () != useUltimate.size () ||
3233+ (localType &&
3234+ (!useType || !localType->IsTkLenCompatibleWith (*useType) ||
3235+ !useType->IsTkLenCompatibleWith (*localType))) ||
3236+ (!localType && useType)) {
3237+ bad = true ;
3238+ } else if (IsNamedConstant (localUltimate)) {
3239+ bad = !IsNamedConstant (useUltimate) ||
3240+ !(*localObject->init () == *useObject->init ());
3241+ } else {
3242+ bad = IsNamedConstant (useUltimate);
3243+ }
3244+ } else {
3245+ bad = true ;
3246+ }
3247+ } else if (useUltimate.has <ObjectEntityDetails>()) {
3248+ bad = true ;
3249+ } else if (IsProcedurePointer (localUltimate)) {
3250+ bad = !IsProcedurePointer (useUltimate);
3251+ } else if (IsProcedurePointer (useUltimate)) {
3252+ bad = true ;
3253+ } else if (localUltimate.has <DerivedTypeDetails>()) {
3254+ bad = !(useUltimate.has <DerivedTypeDetails>() &&
3255+ evaluate::AreSameDerivedTypeIgnoringSequence (
3256+ DerivedTypeSpec{localUltimate.name (), localUltimate},
3257+ DerivedTypeSpec{useUltimate.name (), useUltimate}));
3258+ } else if (useUltimate.has <DerivedTypeDetails>()) {
3259+ bad = true ;
3260+ } else if (localUltimate.has <NamelistDetails>() &&
3261+ useUltimate.has <NamelistDetails>()) {
3262+ } else if (localUltimate.has <CommonBlockDetails>() &&
3263+ useUltimate.has <CommonBlockDetails>()) {
3264+ } else {
3265+ bad = true ;
3266+ }
3267+ if (bad) {
3268+ context
3269+ .Say (location,
3270+ " '%s' use-associated from '%s' in module '%s' is incompatible with '%s' from another module" _err_en_US,
3271+ localName, useUltimate.name (),
3272+ useUltimate.owner ().GetName ().value (), localUltimate.name ())
3273+ .Attach (useUltimate.name (), " First declaration" _en_US)
3274+ .Attach (localUltimate.name (), " Other declaration" _en_US);
3275+ return true ;
3276+ }
3277+ if (auto *msg{context.Warn (
3278+ common::UsageWarning::CompatibleDeclarationsFromDistinctModules,
3279+ location,
3280+ " '%s' is use-associated from '%s' in two distinct instances of module '%s'" _warn_en_US,
3281+ localName, localUltimate.name (),
3282+ localUltimate.owner ().GetName ().value ())}) {
3283+ msg->Attach (localUltimate.name (), " Previous declaration" _en_US)
3284+ .Attach (useUltimate.name (), " Later declaration" _en_US);
3285+ }
3286+ return true ;
3287+ }
3288+
31823289void ModuleVisitor::DoAddUse (SourceName location, SourceName localName,
31833290 Symbol &originalLocal, const Symbol &useSymbol) {
31843291 Symbol *localSymbol{&originalLocal};
@@ -3220,6 +3327,16 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
32203327 return ;
32213328 }
32223329
3330+ if (localUltimate.name () == useUltimate.name () &&
3331+ localUltimate.owner ().IsModule () && useUltimate.owner ().IsModule () &&
3332+ localUltimate.owner ().GetName () &&
3333+ localUltimate.owner ().GetName () == useUltimate.owner ().GetName ()) {
3334+ if (CheckCompatibleDistinctUltimates (context (), location, localName,
3335+ *localSymbol, localUltimate, useUltimate)) {
3336+ return ;
3337+ }
3338+ }
3339+
32233340 // There are many possible combinations of symbol types that could arrive
32243341 // with the same (local) name vie USE association from distinct modules.
32253342 // Fortran allows a generic interface to share its name with a derived type,
@@ -9375,6 +9492,12 @@ template <typename A> std::set<SourceName> GetUses(const A &x) {
93759492}
93769493
93779494bool ResolveNamesVisitor::Pre (const parser::Program &x) {
9495+ if (Scope * hermetic{context ().currentHermeticModuleFileScope ()}) {
9496+ // Processing either the dependent modules or first module of a
9497+ // hermetic module file; ensure that the hermetic module scope has
9498+ // its implicit rules map entry.
9499+ ImplicitRulesVisitor::BeginScope (*hermetic);
9500+ }
93789501 std::map<SourceName, const parser::ProgramUnit *> modules;
93799502 std::set<SourceName> uses;
93809503 bool disordered{false };
0 commit comments