diff options
Diffstat (limited to 'flang/lib/Semantics/tools.cpp')
| -rw-r--r-- | flang/lib/Semantics/tools.cpp | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp index 913bf08cd0d9..28829d3eda30 100644 --- a/flang/lib/Semantics/tools.cpp +++ b/flang/lib/Semantics/tools.cpp @@ -705,7 +705,7 @@ SymbolVector FinalsForDerivedTypeInstantiation(const DerivedTypeSpec &spec) { const Symbol *IsFinalizable(const Symbol &symbol, std::set<const DerivedTypeSpec *> *inProgress, bool withImpureFinalizer) { - if (IsPointer(symbol) || evaluate::IsAssumedRank(symbol)) { + if (IsPointer(symbol) || IsAssumedRank(symbol)) { return nullptr; } if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()}) { @@ -741,7 +741,7 @@ const Symbol *IsFinalizable(const DerivedTypeSpec &derived, if (const SubprogramDetails * subp{symbol->detailsIf<SubprogramDetails>()}) { if (const auto &args{subp->dummyArgs()}; !args.empty() && - args.at(0) && !evaluate::IsAssumedRank(*args.at(0)) && + args.at(0) && !IsAssumedRank(*args.at(0)) && args.at(0)->Rank() != *rank) { continue; // not a finalizer for this rank } @@ -790,7 +790,7 @@ const Symbol *HasImpureFinal(const Symbol &original, std::optional<int> rank) { if (symbol.has<ObjectEntityDetails>()) { if (const DeclTypeSpec * symType{symbol.GetType()}) { if (const DerivedTypeSpec * derived{symType->AsDerived()}) { - if (evaluate::IsAssumedRank(symbol)) { + if (IsAssumedRank(symbol)) { // finalizable assumed-rank not allowed (C839) return nullptr; } else { @@ -1170,7 +1170,7 @@ bool IsAccessible(const Symbol &original, const Scope &scope) { } std::optional<parser::MessageFormattedText> CheckAccessibleSymbol( - const Scope &scope, const Symbol &symbol) { + const Scope &scope, const Symbol &symbol, bool inStructureConstructor) { if (IsAccessible(symbol, scope)) { return std::nullopt; } else if (FindModuleFileContaining(scope)) { @@ -1179,10 +1179,20 @@ std::optional<parser::MessageFormattedText> CheckAccessibleSymbol( // whose structure constructors reference private components. return std::nullopt; } else { + const Scope &module{DEREF(FindModuleContaining(symbol.owner()))}; + // Subtlety: Sometimes we want to be able to convert a generated + // module file back into Fortran, perhaps to convert it into a + // hermetic module file. Don't emit a fatal error for things like + // "__builtin_c_ptr(__address=0)" that came from expansions of + // "cptr_null()"; specifically, just warn about structure constructor + // component names from intrinsic modules when in a module. + parser::MessageFixedText text{FindModuleContaining(scope) && + module.parent().IsIntrinsicModules() && + inStructureConstructor && symbol.owner().IsDerivedType() + ? "PRIVATE name '%s' is accessible only within module '%s'"_warn_en_US + : "PRIVATE name '%s' is accessible only within module '%s'"_err_en_US}; return parser::MessageFormattedText{ - "PRIVATE name '%s' is accessible only within module '%s'"_err_en_US, - symbol.name(), - DEREF(FindModuleContaining(symbol.owner())).GetName().value()}; + std::move(text), symbol.name(), module.GetName().value()}; } } |
