@@ -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;
@@ -3183,6 +3185,92 @@ static bool ConvertToUseError(
31833185 }
31843186}
31853187
3188+ // Two ultimate symbols are distinct, but they have the same name and come
3189+ // from modules with the same name. At link time, their mangled names
3190+ // would conflict, so they had better resolve to the same definition.
3191+ // Check whether the two ultimate symbols have compatible definitions.
3192+ // Returns true if no further processing is required in DoAddUse().
3193+ static bool CheckCompatibleDistinctUltimates (SemanticsContext &context,
3194+ SourceName location, SourceName localName, const Symbol &localSymbol,
3195+ const Symbol &localUltimate, const Symbol &useUltimate, bool &isError) {
3196+ isError = false ;
3197+ if (localUltimate.has <GenericDetails>()) {
3198+ if (useUltimate.has <GenericDetails>() ||
3199+ useUltimate.has <SubprogramDetails>() ||
3200+ useUltimate.has <DerivedTypeDetails>()) {
3201+ return false ; // can try to merge them
3202+ } else {
3203+ isError = true ;
3204+ }
3205+ } else if (useUltimate.has <GenericDetails>()) {
3206+ if (localUltimate.has <SubprogramDetails>() ||
3207+ localUltimate.has <DerivedTypeDetails>()) {
3208+ return false ; // can try to merge them
3209+ } else {
3210+ isError = true ;
3211+ }
3212+ } else if (localUltimate.has <SubprogramDetails>()) {
3213+ if (useUltimate.has <SubprogramDetails>()) {
3214+ auto localCharacteristics{
3215+ evaluate::characteristics::Procedure::Characterize (
3216+ localUltimate, context.foldingContext ())};
3217+ auto useCharacteristics{
3218+ evaluate::characteristics::Procedure::Characterize (
3219+ useUltimate, context.foldingContext ())};
3220+ if ((localCharacteristics &&
3221+ (!useCharacteristics ||
3222+ *localCharacteristics != *useCharacteristics)) ||
3223+ (!localCharacteristics && useCharacteristics)) {
3224+ isError = true ;
3225+ }
3226+ } else {
3227+ isError = true ;
3228+ }
3229+ } else if (useUltimate.has <SubprogramDetails>()) {
3230+ isError = true ;
3231+ } else if (const auto *localObject{
3232+ localUltimate.detailsIf <ObjectEntityDetails>()}) {
3233+ if (const auto *useObject{useUltimate.detailsIf <ObjectEntityDetails>()}) {
3234+ auto localType{evaluate::DynamicType::From (localUltimate)};
3235+ auto useType{evaluate::DynamicType::From (useUltimate)};
3236+ if (localUltimate.size () != useUltimate.size () ||
3237+ (localType &&
3238+ (!useType || !localType->IsTkLenCompatibleWith (*useType) ||
3239+ !useType->IsTkLenCompatibleWith (*localType))) ||
3240+ (!localType && useType)) {
3241+ isError = true ;
3242+ } else if (IsNamedConstant (localUltimate)) {
3243+ isError = !IsNamedConstant (useUltimate) ||
3244+ !(*localObject->init () == *useObject->init ());
3245+ } else {
3246+ isError = IsNamedConstant (useUltimate);
3247+ }
3248+ } else {
3249+ isError = true ;
3250+ }
3251+ } else if (useUltimate.has <ObjectEntityDetails>()) {
3252+ isError = true ;
3253+ } else if (IsProcedurePointer (localUltimate)) {
3254+ isError = !IsProcedurePointer (useUltimate);
3255+ } else if (IsProcedurePointer (useUltimate)) {
3256+ isError = true ;
3257+ } else if (localUltimate.has <DerivedTypeDetails>()) {
3258+ isError = !(useUltimate.has <DerivedTypeDetails>() &&
3259+ evaluate::AreSameDerivedTypeIgnoringSequence (
3260+ DerivedTypeSpec{localUltimate.name (), localUltimate},
3261+ DerivedTypeSpec{useUltimate.name (), useUltimate}));
3262+ } else if (useUltimate.has <DerivedTypeDetails>()) {
3263+ isError = true ;
3264+ } else if (localUltimate.has <NamelistDetails>() &&
3265+ useUltimate.has <NamelistDetails>()) {
3266+ } else if (localUltimate.has <CommonBlockDetails>() &&
3267+ useUltimate.has <CommonBlockDetails>()) {
3268+ } else {
3269+ isError = true ;
3270+ }
3271+ return true ; // don't try to merge generics (or whatever)
3272+ }
3273+
31863274void ModuleVisitor::DoAddUse (SourceName location, SourceName localName,
31873275 Symbol &originalLocal, const Symbol &useSymbol) {
31883276 Symbol *localSymbol{&originalLocal};
@@ -3224,6 +3312,40 @@ void ModuleVisitor::DoAddUse(SourceName location, SourceName localName,
32243312 return ;
32253313 }
32263314
3315+ if (localUltimate.name () == useUltimate.name () &&
3316+ localUltimate.owner ().IsModule () && useUltimate.owner ().IsModule () &&
3317+ localUltimate.owner ().GetName () &&
3318+ localUltimate.owner ().GetName () == useUltimate.owner ().GetName ()) {
3319+ bool isError{false };
3320+ if (CheckCompatibleDistinctUltimates (context (), location, localName,
3321+ *localSymbol, localUltimate, useUltimate, isError)) {
3322+ if (isError) {
3323+ // Convert the local symbol to a UseErrorDetails, if possible;
3324+ // otherwise emit a fatal error.
3325+ if (!ConvertToUseError (*localSymbol, location, *useModuleScope_)) {
3326+ context ()
3327+ .Say (location,
3328+ " '%s' use-associated from '%s' in module '%s' is incompatible with '%s' from another module" _err_en_US,
3329+ localName, useUltimate.name (),
3330+ useUltimate.owner ().GetName ().value (), localUltimate.name ())
3331+ .Attach (useUltimate.name (), " First declaration" _en_US)
3332+ .Attach (localUltimate.name (), " Other declaration" _en_US);
3333+ return ;
3334+ }
3335+ }
3336+ if (auto *msg{context ().Warn (
3337+ common::UsageWarning::CompatibleDeclarationsFromDistinctModules,
3338+ location,
3339+ " '%s' is use-associated from '%s' in two distinct instances of module '%s'" _warn_en_US,
3340+ localName, localUltimate.name (),
3341+ localUltimate.owner ().GetName ().value ())}) {
3342+ msg->Attach (localUltimate.name (), " Previous declaration" _en_US)
3343+ .Attach (useUltimate.name (), " Later declaration" _en_US);
3344+ }
3345+ return ;
3346+ }
3347+ }
3348+
32273349 // There are many possible combinations of symbol types that could arrive
32283350 // with the same (local) name vie USE association from distinct modules.
32293351 // Fortran allows a generic interface to share its name with a derived type,
@@ -9376,6 +9498,12 @@ template <typename A> std::set<SourceName> GetUses(const A &x) {
93769498}
93779499
93789500bool ResolveNamesVisitor::Pre (const parser::Program &x) {
9501+ if (Scope * hermetic{context ().currentHermeticModuleFileScope ()}) {
9502+ // Processing either the dependent modules or first module of a
9503+ // hermetic module file; ensure that the hermetic module scope has
9504+ // its implicit rules map entry.
9505+ ImplicitRulesVisitor::BeginScope (*hermetic);
9506+ }
93799507 std::map<SourceName, const parser::ProgramUnit *> modules;
93809508 std::set<SourceName> uses;
93819509 bool disordered{false };
0 commit comments