diff options
author | Peter Klausler <35819229+klausler@users.noreply.github.com> | 2023-10-16 17:29:25 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-16 17:29:25 -0700 |
commit | 81d04709f86968431ecab1df12a17279d057daa9 (patch) | |
tree | a3dc018b6a2b664fcee4194b163d75c732122eb6 /flang/lib/Parser/executable-parsers.cpp | |
parent | 11d07d9ef618497b825badee8b4f06a48575606b (diff) | |
download | llvm-81d04709f86968431ecab1df12a17279d057daa9.zip llvm-81d04709f86968431ecab1df12a17279d057daa9.tar.gz llvm-81d04709f86968431ecab1df12a17279d057daa9.tar.bz2 |
[flang] Fix construct names on labeled DO (#67622)
Fortran requires that a DO construct with a construct name end with an
END DO statement bearing the same name. This is true even if the DO
construct begins with a label DO statement; e.g., "constrName: do 10
j=1,10" must end with "10 end do constrName".
The compiler presently basically ignores construct names that appear on
label DO statements, because only non-label DO statements can be parsed
as DO constructs. This causes us to miss some errors, and (worse) breaks
the usage of the construct name on CYCLE and EXIT statements.
To fix this, this patch changes the parse tree and parser so that a DO
construct name on a putative label DO statement causes it to be parsed
as a "non-label" DO statement... with a label. Only true old-style
labeled DO statements without construct names are now parsed as such.
I did not change the class name NonLabelDoStmt -- it's widely used
across the front-end, and is the name of a production in the standard's
grammar. But now it basically means DoConstructDoStmt.
Fixes https://github.com/llvm/llvm-project/issues/67283.
Diffstat (limited to 'flang/lib/Parser/executable-parsers.cpp')
-rw-r--r-- | flang/lib/Parser/executable-parsers.cpp | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/flang/lib/Parser/executable-parsers.cpp b/flang/lib/Parser/executable-parsers.cpp index a61bf2c..892c612 100644 --- a/flang/lib/Parser/executable-parsers.cpp +++ b/flang/lib/Parser/executable-parsers.cpp @@ -279,13 +279,17 @@ TYPE_CONTEXT_PARSER("loop control"_en_US, many(Parser<LocalitySpec>{}))))) // R1121 label-do-stmt -> [do-construct-name :] DO label [loop-control] +// A label-do-stmt with a do-construct-name is parsed as a nonlabel-do-stmt +// with an optional label. TYPE_CONTEXT_PARSER("label DO statement"_en_US, - construct<LabelDoStmt>( - maybe(name / ":"), "DO" >> label, maybe(loopControl))) + construct<LabelDoStmt>("DO" >> label, maybe(loopControl))) // R1122 nonlabel-do-stmt -> [do-construct-name :] DO [loop-control] TYPE_CONTEXT_PARSER("nonlabel DO statement"_en_US, - construct<NonLabelDoStmt>(maybe(name / ":"), "DO" >> maybe(loopControl))) + construct<NonLabelDoStmt>( + name / ":", "DO" >> maybe(label), maybe(loopControl)) || + construct<NonLabelDoStmt>(construct<std::optional<Name>>(), + construct<std::optional<Label>>(), "DO" >> maybe(loopControl))) // R1132 end-do-stmt -> END DO [do-construct-name] TYPE_CONTEXT_PARSER("END DO statement"_en_US, |