forked from OSchip/llvm-project
[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:
parent
acd1cab2d4
commit
facd7147f4
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue