@@ -2259,85 +2259,86 @@ void OmpAttributeVisitor::CheckPerfectNestAndRectangularLoop(
22592259 // Find the associated region by skipping nested loop-associated constructs
22602260 // such as loop transformations
22612261 const parser::NestedConstruct *innermostAssocRegion{nullptr };
2262- const parser::OpenMPLoopConstruct *innermostConstruct{&x} ;
2263- while ( const auto &innerAssocStmt{
2264- std::get<std::optional <parser::NestedConstruct>>(
2265- innermostConstruct-> t )} ) {
2266- innermostAssocRegion = &(innerAssocStmt. value ()) ;
2262+ const parser::OpenMPLoopConstruct *innermostConstruct = &x ;
2263+ auto &loopConsList =
2264+ std::get<std::list <parser::NestedConstruct>>(innermostConstruct-> t );
2265+ for ( auto &loopCons : loopConsList ) {
2266+ innermostAssocRegion = &loopCons ;
22672267 if (const auto *innerConstruct{
22682268 std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(
22692269 innermostAssocRegion)}) {
2270- innermostConstruct = &innerConstruct->value ();
2270+ CheckPerfectNestAndRectangularLoop (innerConstruct->value ());
2271+ return ;
22712272 } else {
2272- break ;
2273- }
2274- }
22752273
2276- if (!innermostAssocRegion)
2277- return ;
2278- const auto &outer{std::get_if<parser::DoConstruct>(innermostAssocRegion)};
2279- if (!outer)
2280- return ;
2274+ if (!innermostAssocRegion)
2275+ continue ;
2276+ const auto &outer{std::get_if<parser::DoConstruct>(innermostAssocRegion)};
2277+ if (!outer)
2278+ continue ;
22812279
2282- llvm::SmallVector<Symbol *> ivs;
2283- int curLevel{0 };
2284- const parser::DoConstruct *loop{outer};
2285- while (true ) {
2286- auto [iv, lb, ub, step] = GetLoopBounds (*loop);
2287-
2288- if (lb)
2289- checkExprHasSymbols (ivs, lb);
2290- if (ub)
2291- checkExprHasSymbols (ivs, ub);
2292- if (step)
2293- checkExprHasSymbols (ivs, step);
2294- if (iv) {
2295- if (auto *symbol{currScope ().FindSymbol (iv->source )})
2296- ivs.push_back (symbol);
2297- }
2280+ llvm::SmallVector<Symbol *> ivs;
2281+ int curLevel{0 };
2282+ const parser::DoConstruct *loop{outer};
2283+ while (true ) {
2284+ auto [iv, lb, ub, step] = GetLoopBounds (*loop);
2285+
2286+ if (lb)
2287+ checkExprHasSymbols (ivs, lb);
2288+ if (ub)
2289+ checkExprHasSymbols (ivs, ub);
2290+ if (step)
2291+ checkExprHasSymbols (ivs, step);
2292+ if (iv) {
2293+ if (auto *symbol{currScope ().FindSymbol (iv->source )})
2294+ ivs.push_back (symbol);
2295+ }
22982296
2299- // Stop after processing all affected loops
2300- if (curLevel + 1 >= dirDepth)
2301- break ;
2297+ // Stop after processing all affected loops
2298+ if (curLevel + 1 >= dirDepth)
2299+ break ;
23022300
2303- // Recurse into nested loop
2304- const auto &block{std::get<parser::Block>(loop->t )};
2305- if (block.empty ()) {
2306- // Insufficient number of nested loops already reported by
2307- // CheckAssocLoopLevel()
2308- break ;
2309- }
2301+ // Recurse into nested loop
2302+ const auto &block{std::get<parser::Block>(loop->t )};
2303+ if (block.empty ()) {
2304+ // Insufficient number of nested loops already reported by
2305+ // CheckAssocLoopLevel()
2306+ break ;
2307+ }
23102308
2311- loop = GetDoConstructIf (block.front ());
2312- if (!loop) {
2313- // Insufficient number of nested loops already reported by
2314- // CheckAssocLoopLevel()
2315- break ;
2316- }
2309+ loop = GetDoConstructIf (block.front ());
2310+ if (!loop) {
2311+ // Insufficient number of nested loops already reported by
2312+ // CheckAssocLoopLevel()
2313+ break ;
2314+ }
23172315
2318- auto checkPerfectNest = [&, this ]() {
2319- if (block.empty ())
2320- return ;
2321- auto last = block.end ();
2322- --last;
2316+ auto checkPerfectNest = [&, this ]() {
2317+ if (block.empty ())
2318+ return ;
2319+ auto last = block.end ();
2320+ --last;
23232321
2324- // A trailing CONTINUE is not considered part of the loop body
2325- if (parser::Unwrap<parser::ContinueStmt>(*last))
2326- --last;
2322+ // A trailing CONTINUE is not considered part of the loop body
2323+ if (parser::Unwrap<parser::ContinueStmt>(*last))
2324+ --last;
23272325
2328- // In a perfectly nested loop, the nested loop must be the only statement
2329- if (last == block.begin ())
2330- return ;
2326+ // In a perfectly nested loop, the nested loop must be the only
2327+ // statement
2328+ if (last == block.begin ())
2329+ return ;
23312330
2332- // Non-perfectly nested loop
2333- // TODO: Point to non-DO statement, directiveSource as a note
2334- context_.Say (dirContext.directiveSource ,
2335- " Canonical loop nest must be perfectly nested." _err_en_US);
2336- };
2331+ // Non-perfectly nested loop
2332+ // TODO: Point to non-DO statement, directiveSource as a note
2333+ context_.Say (dirContext.directiveSource ,
2334+ " Canonical loop nest must be perfectly nested." _err_en_US);
2335+ };
23372336
2338- checkPerfectNest ();
2337+ checkPerfectNest ();
23392338
2340- ++curLevel;
2339+ ++curLevel;
2340+ }
2341+ }
23412342 }
23422343}
23432344
0 commit comments