[flang] Fix internal error due to missing type

If a name is declared in a module with just `private :: x`,
we don't know if `x` is supposed to be an object or procedure,
so it ends up not getting an implicit type. This leads to an
internal error when writing the `.mod` file.

The fix requires two changes:
1. Cause all `EntityDetails` to be converted to `ObjectEntityDetails`
   in `ResolveSpecificationParts`. This is done by calling `PopScope()`.
   The reason for not calling it there no longer applies since the
   addition of the `ExecutionPartSkimmer` pass.
2. In the same place, apply the implicit typing rules to every entity
   in the scope.

Fixes flang-compiler/f18#514, fixes flang-compiler/f18#520.

Original-commit: flang-compiler/f18@7e4185e9ff
Reviewed-on: https://github.com/flang-compiler/f18/pull/524
This commit is contained in:
Tim Keith 2019-06-24 15:22:57 -07:00
parent acd1cab2d4
commit facd7147f4
3 changed files with 45 additions and 28 deletions

View File

@ -1669,18 +1669,15 @@ void ScopeHandler::EraseSymbol(const parser::Name &name) {
} }
static bool NeedsType(const Symbol &symbol) { static bool NeedsType(const Symbol &symbol) {
if (symbol.GetType()) { return symbol.GetType() == nullptr &&
return false; std::visit(
} common::visitors{
if (auto *details{symbol.detailsIf<ProcEntityDetails>()}) { [](const EntityDetails &) { return true; },
if (details->interface().symbol()) { [](const ObjectEntityDetails &) { return true; },
return false; // the interface determines the type [](const AssocEntityDetails &) { return true; },
} [](const auto &) { return false; },
if (!symbol.test(Symbol::Flag::Function)) { },
return false; // not known to be a function symbol.details());
}
}
return true;
} }
void ScopeHandler::ApplyImplicitRules(Symbol &symbol) { void ScopeHandler::ApplyImplicitRules(Symbol &symbol) {
if (NeedsType(symbol)) { if (NeedsType(symbol)) {
@ -4835,22 +4832,11 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
ResolveSpecificationParts(child); ResolveSpecificationParts(child);
} }
ExecutionPartSkimmer{scope}.Walk(node.exec()); ExecutionPartSkimmer{scope}.Walk(node.exec());
// Convert function results and dummy arguments to objects if we don't PopScope();
// already known by now that they're procedures. // Ensure every object entity has a type:
if (currScope().kind() == Scope::Kind::Subprogram) { for (auto &pair : *node.scope()) {
for (const auto &pair : currScope()) { ApplyImplicitRules(*pair.second);
Symbol &symbol{*pair.second};
if (auto *details{symbol.detailsIf<EntityDetails>()}) {
if (details->isFuncResult() || details->isDummy()) {
ConvertToObjectEntity(symbol);
}
}
}
} }
// Subtlety: PopScope() is not called here because we want to defer
// conversions of other uncategorized entities into objects until after
// we have traversed the executable part of the subprogram.
SetScope(currScope().parent());
} }
// Add SubprogramNameDetails symbols for contained subprograms // Add SubprogramNameDetails symbols for contained subprograms

View File

@ -129,7 +129,7 @@ set(ERROR_TESTS
expr-errors01.f90 expr-errors01.f90
null01.f90 null01.f90
equivalence01.f90 equivalence01.f90
# ${PROJECT_SOURCE_DIR}/module/ieee_arithmetic.f90 #520 ${PROJECT_SOURCE_DIR}/module/ieee_arithmetic.f90
${PROJECT_SOURCE_DIR}/module/ieee_exceptions.f90 ${PROJECT_SOURCE_DIR}/module/ieee_exceptions.f90
${PROJECT_SOURCE_DIR}/module/ieee_features.f90 ${PROJECT_SOURCE_DIR}/module/ieee_features.f90
${PROJECT_SOURCE_DIR}/module/iso_c_binding.f90 ${PROJECT_SOURCE_DIR}/module/iso_c_binding.f90
@ -185,6 +185,7 @@ set(MODFILE_TESTS
modfile26.f90 modfile26.f90
modfile27.f90 modfile27.f90
modfile28.f90 modfile28.f90
modfile29.f90
) )
set(LABEL_TESTS set(LABEL_TESTS

View File

@ -0,0 +1,30 @@
! Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
! http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
! Check that implicitly typed entities get a type in the module file.
module m
public :: a
private :: b
protected :: i
allocatable :: j
end
!Expect: m.mod
!module m
! real(4)::a
! real(4),private::b
! integer(4),protected::i
! integer(4),allocatable::j
!end