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 &); @@ -58,6 +59,7 @@ private: SemanticsContext &context_; + int exprDepth_{0}; void SayBadLeave( StmtType, const char *enclosingStmt, const ConstructNode &) const; 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,16 @@ template ActualArgumentSet CollectActualArguments(const SomeExpr &); +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