diff --git a/flang/lib/Semantics/check-do-forall.h b/flang/lib/Semantics/check-do-forall.h --- a/flang/lib/Semantics/check-do-forall.h +++ b/flang/lib/Semantics/check-do-forall.h @@ -50,6 +50,7 @@ void Leave(const parser::ForallStmt &); void Leave(const parser::ForallAssignmentStmt &s); void Enter(const parser::ExitStmt &); + void Enter(const parser::Expr &); void Leave(const parser::Expr &); void Leave(const parser::InquireSpec &); void Leave(const parser::IoControlSpec &); diff --git a/flang/lib/Semantics/check-do-forall.cpp b/flang/lib/Semantics/check-do-forall.cpp --- a/flang/lib/Semantics/check-do-forall.cpp +++ b/flang/lib/Semantics/check-do-forall.cpp @@ -1034,7 +1034,8 @@ CollectActualArgumentsHelper() : Base{*this} {} using Base::operator(); ActualArgumentSet operator()(const evaluate::ActualArgument &arg) const { - return ActualArgumentSet{arg}; + return Combine(ActualArgumentSet{arg}, + CollectActualArgumentsHelper{}(arg.UnwrapExpr())); } }; @@ -1044,11 +1045,18 @@ template ActualArgumentSet CollectActualArguments(const SomeExpr &); +static int exprDepth{0}; + +void DoForallChecker::Enter(const parser::Expr &parsedExpr) { ++exprDepth; } + void DoForallChecker::Leave(const parser::Expr &parsedExpr) { - if (const SomeExpr * expr{GetExpr(parsedExpr)}) { - ActualArgumentSet argSet{CollectActualArguments(*expr)}; - for (const evaluate::ActualArgumentRef &argRef : argSet) { - CheckIfArgIsDoVar(*argRef, parsedExpr.source, context_); + CHECK(exprDepth > 0); + if (--exprDepth == 0) { // Only check top level expressions + if (const SomeExpr * expr{GetExpr(parsedExpr)}) { + ActualArgumentSet argSet{CollectActualArguments(*expr)}; + for (const evaluate::ActualArgumentRef &argRef : argSet) { + CheckIfArgIsDoVar(*argRef, parsedExpr.source, context_); + } } } } diff --git a/flang/test/Semantics/resolve91.f90 b/flang/test/Semantics/resolve91.f90 --- a/flang/test/Semantics/resolve91.f90 +++ b/flang/test/Semantics/resolve91.f90 @@ -44,3 +44,15 @@ real, dimension(:), pointer :: realArray => localArray end type end module m4 + +module m6 + integer, dimension(3) :: iarray + !ERROR: Derived type 'ubound' not found + character(len=ubound(iarray)(1)) :: first +end module m6 + +module m7 + integer, dimension(2) :: iarray + !ERROR: Derived type 'ubound' not found + integer :: ivar = ubound(iarray)(1) +end module m7