diff options
author | Krzysztof Parzyszek <Krzysztof.Parzyszek@amd.com> | 2025-07-25 08:42:23 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-25 08:42:23 -0500 |
commit | 6b92a3bc21cdcdeb161a06524a9860551831c67e (patch) | |
tree | 82f6d2680b1f3274553431e0f46fbf8a71ec48bd /flang/lib | |
parent | b75530ff034a131da8ca1f05a00f3655c13839ff (diff) | |
download | llvm-6b92a3bc21cdcdeb161a06524a9860551831c67e.zip llvm-6b92a3bc21cdcdeb161a06524a9860551831c67e.tar.gz llvm-6b92a3bc21cdcdeb161a06524a9860551831c67e.tar.bz2 |
[flang][OpenMP] Detect BLOCK construct through lookahead (#150617)
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.
Diffstat (limited to 'flang/lib')
-rw-r--r-- | flang/lib/Parser/openmp-parsers.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 25a692d..1c62614 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<resultType> Parse(ParseState &state) const { - if (auto epc{Parser<ExecutionPartConstruct>{}.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<ExecutionPartConstruct>{}.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<resultType> 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<ExecutionPartConstruct>{}).Parse(state)}) { if (!IsFortranBlockConstruct(*epc)) { |