From 11e2a91da6cd77d526ece0b640033360b720652d Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Fri, 25 Jul 2025 08:17:55 -0500 Subject: [PATCH] [flang][OpenMP] Detect BLOCK construct through lookahead Avoid parsing the entire ExecutionPartConstruct in either the strictly- or the loosely-structured block parser only to discard it when it's not BLOCK (or is BLOCK) respectively. Doing so was not incorrct, but in pathological cases (like Fujitsu 0981_0034) the recursive parsing can take a very long time. Instead, detect the presence of BLOCK first (via a simple lookahead), and fail immediately if necessary. --- flang/lib/Parser/openmp-parsers.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 25a692deba3cc..1c626148a03ae 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1222,11 +1222,14 @@ struct StrictlyStructuredBlockParser { using resultType = Block; std::optional Parse(ParseState &state) const { - if (auto epc{Parser{}.Parse(state)}) { - if (IsFortranBlockConstruct(*epc)) { - Block block; - block.emplace_back(std::move(*epc)); - return std::move(block); + // Detect BLOCK construct without parsing the entire thing. + if (lookAhead(skipStuffBeforeStatement >> "BLOCK"_tok).Parse(state)) { + if (auto epc{Parser{}.Parse(state)}) { + if (IsFortranBlockConstruct(*epc)) { + Block block; + block.emplace_back(std::move(*epc)); + return std::move(block); + } } } return std::nullopt; @@ -1237,6 +1240,10 @@ struct LooselyStructuredBlockParser { using resultType = Block; std::optional Parse(ParseState &state) const { + // Detect BLOCK construct without parsing the entire thing. + if (lookAhead(skipStuffBeforeStatement >> "BLOCK"_tok).Parse(state)) { + return std::nullopt; + } Block body; if (auto epc{attempt(Parser{}).Parse(state)}) { if (!IsFortranBlockConstruct(*epc)) {