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) {
|
||||
if (symbol.GetType()) {
|
||||
return false;
|
||||
}
|
||||
if (auto *details{symbol.detailsIf<ProcEntityDetails>()}) {
|
||||
if (details->interface().symbol()) {
|
||||
return false; // the interface determines the type
|
||||
}
|
||||
if (!symbol.test(Symbol::Flag::Function)) {
|
||||
return false; // not known to be a function
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return symbol.GetType() == nullptr &&
|
||||
std::visit(
|
||||
common::visitors{
|
||||
[](const EntityDetails &) { return true; },
|
||||
[](const ObjectEntityDetails &) { return true; },
|
||||
[](const AssocEntityDetails &) { return true; },
|
||||
[](const auto &) { return false; },
|
||||
},
|
||||
symbol.details());
|
||||
}
|
||||
void ScopeHandler::ApplyImplicitRules(Symbol &symbol) {
|
||||
if (NeedsType(symbol)) {
|
||||
|
@ -4835,22 +4832,11 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
|
|||
ResolveSpecificationParts(child);
|
||||
}
|
||||
ExecutionPartSkimmer{scope}.Walk(node.exec());
|
||||
// Convert function results and dummy arguments to objects if we don't
|
||||
// already known by now that they're procedures.
|
||||
if (currScope().kind() == Scope::Kind::Subprogram) {
|
||||
for (const auto &pair : currScope()) {
|
||||
Symbol &symbol{*pair.second};
|
||||
if (auto *details{symbol.detailsIf<EntityDetails>()}) {
|
||||
if (details->isFuncResult() || details->isDummy()) {
|
||||
ConvertToObjectEntity(symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
PopScope();
|
||||
// Ensure every object entity has a type:
|
||||
for (auto &pair : *node.scope()) {
|
||||
ApplyImplicitRules(*pair.second);
|
||||
}
|
||||
// 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
|
||||
|
|
|
@ -129,7 +129,7 @@ set(ERROR_TESTS
|
|||
expr-errors01.f90
|
||||
null01.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_features.f90
|
||||
${PROJECT_SOURCE_DIR}/module/iso_c_binding.f90
|
||||
|
@ -185,6 +185,7 @@ set(MODFILE_TESTS
|
|||
modfile26.f90
|
||||
modfile27.f90
|
||||
modfile28.f90
|
||||
modfile29.f90
|
||||
)
|
||||
|
||||
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