From 45b869e5c4a37a01f74aa2b457907a32104197c9 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Wed, 17 Jul 2024 12:28:18 -0700 Subject: [PATCH] [flang] A nested STRUCTURE must declare entities When a DEC legacy STRUCTURE definition appears within another, its STRUCTURE statement must also declare some components of the enclosing structure. Fixes https://github.com/llvm/llvm-project/issues/99288. --- flang/lib/Parser/Fortran-parsers.cpp | 16 ++++++++++++---- flang/test/Semantics/struct03.f90 | 7 +++++++ 2 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 flang/test/Semantics/struct03.f90 diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp index 746d04ad649d1..0bdc4c4e033c7 100644 --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -1304,10 +1304,16 @@ TYPE_PARSER(extension(construct( defaulted( maybe("::"_tok) >> nonemptyList("expected names"_err_en_US, name))))) -// Subtle: the name includes the surrounding slashes, which avoids +// Subtle: A structure's name includes the surrounding slashes, which avoids // clashes with other uses of the name in the same scope. -TYPE_PARSER(construct( - "STRUCTURE" >> maybe(sourced("/" >> name / "/")), optionalList(entityDecl))) +constexpr auto structureName{maybe(sourced("/" >> name / "/"))}; + +// Note that Parser{} has a mandatory list of entity-decls +// and is used only by NestedStructureStmt{}.Parse() in user-state.cpp. +TYPE_PARSER(construct("STRUCTURE" >> structureName, + localRecovery( + "entity declarations are required on a nested structure"_err_en_US, + nonemptyList(entityDecl), ok))) constexpr auto nestedStructureDef{ CONTEXT_PARSER("nested STRUCTURE definition"_en_US, @@ -1323,7 +1329,9 @@ TYPE_PARSER(construct(statement(StructureComponents{})) || TYPE_CONTEXT_PARSER("STRUCTURE definition"_en_US, extension( "nonstandard usage: STRUCTURE"_port_en_US, - construct(statement(Parser{}), + construct( + statement(construct( + "STRUCTURE" >> structureName, optionalList(entityDecl))), many(Parser{}), statement(construct( "END STRUCTURE"_tok))))) diff --git a/flang/test/Semantics/struct03.f90 b/flang/test/Semantics/struct03.f90 new file mode 100644 index 0000000000000..a334cca8945fc --- /dev/null +++ b/flang/test/Semantics/struct03.f90 @@ -0,0 +1,7 @@ +! RUN: %python %S/test_errors.py %s %flang_fc1 + structure /s/ + !ERROR: entity declarations are required on a nested structure + structure /nested/ + end structure + end structure +end