[flang] Fix type resolution in ConcurrentHeader

As it was implemented we weren't detecting non-constant kind parameters
in the integer-type-spec. The fix is just to walk the integer-type-spec
like was do any other one.

Also, there is not need for ResolveControlExpressions -- all it does is
walk that part of the parse tree.

Original-commit: flang-compiler/f18@8c0d890eb8
Reviewed-on: https://github.com/flang-compiler/f18/pull/904
Tree-same-pre-rewrite: false
This commit is contained in:
Tim Keith 2019-12-23 14:19:24 -08:00
parent 83d574bf07
commit ec88d6780f
2 changed files with 12 additions and 25 deletions

View File

@ -1039,7 +1039,6 @@ private:
void SetTypeFromAssociation(Symbol &);
void SetAttrsFromAssociation(Symbol &);
Selector ResolveSelector(const parser::Selector &);
void ResolveControlExpressions(const parser::ConcurrentControl &control);
void ResolveIndexName(const parser::ConcurrentControl &control);
Association &GetCurrentAssociation();
void PushAssociation();
@ -4605,41 +4604,19 @@ void ConstructVisitor::ResolveIndexName(
EvaluateExpr(parser::Scalar{parser::Integer{common::Clone(name)}});
}
void ConstructVisitor::ResolveControlExpressions(
const parser::ConcurrentControl &control) {
Walk(std::get<1>(control.t)); // Initial expression
Walk(std::get<2>(control.t)); // Final expression
Walk(std::get<3>(control.t)); // Step expression
}
// We need to make sure that all of the index-names get declared before the
// expressions in the loop control are evaluated so that references to the
// index-names in the expressions are correctly detected.
bool ConstructVisitor::Pre(const parser::ConcurrentHeader &header) {
BeginDeclTypeSpec();
// Process the type spec, if present
const auto &typeSpec{
std::get<std::optional<parser::IntegerTypeSpec>>(header.t)};
if (typeSpec) {
SetDeclTypeSpec(MakeNumericType(TypeCategory::Integer, typeSpec->v));
}
// Process the index-name nodes in the ConcurrentControl nodes
Walk(std::get<std::optional<parser::IntegerTypeSpec>>(header.t));
const auto &controls{
std::get<std::list<parser::ConcurrentControl>>(header.t)};
for (const auto &control : controls) {
ResolveIndexName(control);
}
// Process the expressions in ConcurrentControls
for (const auto &control : controls) {
ResolveControlExpressions(control);
}
// Resolve the names in the scalar-mask-expr
Walk(controls);
Walk(std::get<std::optional<parser::ScalarLogicalExpr>>(header.t));
EndDeclTypeSpec();
return false;
}

View File

@ -69,6 +69,16 @@ contains
end
end
subroutine s6b
integer, parameter :: k = 4
integer :: l = 4
forall(integer(k) :: i = 1:10)
end forall
!ERROR: Must be a constant value
forall(integer(l) :: i = 1:10)
end forall
end
subroutine s7
!ERROR: 'i' is already declared in this scoping unit
do concurrent(integer::i=1:5) local(j, i) &