diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 1d97126d17dbc4..f87a1cfceb37ba 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -1481,9 +1481,10 @@ struct DataStmtConstant { UNION_CLASS_BOILERPLATE(DataStmtConstant); CharBlock source; mutable TypedExpr typedExpr; - std::variant, StructureConstructor> + std::variant, + LiteralConstant, SignedIntLiteralConstant, SignedRealLiteralConstant, + SignedComplexLiteralConstant, NullInit, common::Indirection, + StructureConstructor> u; }; diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp index a3d2c363108073..aa0a2a6db7d588 100644 --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -929,8 +929,11 @@ TYPE_PARSER(construct(intLiteralConstant) || // components can be ambiguous with a scalar-constant-subobject. // So we parse literal constants, designator, null-init, and // structure-constructor, so that semantics can figure things out later -// with the symbol table. -TYPE_PARSER(sourced(first(construct(literalConstant), +// with the symbol table. A literal constant substring must be attempted +// first to avoid a partial match with a literal constant. +TYPE_PARSER(sourced(first( + construct(indirect(charLiteralConstantSubstring)), + construct(literalConstant), construct(signedRealLiteralConstant), construct(signedIntLiteralConstant), extension( diff --git a/flang/lib/Parser/expr-parsers.cpp b/flang/lib/Parser/expr-parsers.cpp index 77a13de7fd02d8..0b6e21e1ba2ff2 100644 --- a/flang/lib/Parser/expr-parsers.cpp +++ b/flang/lib/Parser/expr-parsers.cpp @@ -68,7 +68,7 @@ TYPE_PARSER(construct( // type-param-inquiry is parsed as a structure component, except for // substring%KIND/LEN constexpr auto primary{instrumented("primary"_en_US, - first(construct(indirect(Parser{})), + first(construct(indirect(charLiteralConstantSubstring)), construct(literalConstant), construct(construct("(" >> expr / !","_tok / recovery(")"_tok, SkipPastNested<'(', ')'>{}))), diff --git a/flang/lib/Parser/type-parsers.h b/flang/lib/Parser/type-parsers.h index d7e0cd06c3f444..623437f9d2e1d8 100644 --- a/flang/lib/Parser/type-parsers.h +++ b/flang/lib/Parser/type-parsers.h @@ -63,6 +63,7 @@ constexpr Parser kindParam; // R709 constexpr Parser realLiteralConstant; // R714 constexpr Parser charLength; // R723 constexpr Parser charLiteralConstant; // R724 +constexpr Parser charLiteralConstantSubstring; constexpr Parser initialization; // R743 & R805 constexpr Parser derivedTypeSpec; // R754 constexpr Parser typeDeclarationStmt; // R801 diff --git a/flang/test/Parser/lit-substr-data.f90 b/flang/test/Parser/lit-substr-data.f90 new file mode 100644 index 00000000000000..7eed616a1ee2ec --- /dev/null +++ b/flang/test/Parser/lit-substr-data.f90 @@ -0,0 +1,7 @@ +!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s +!Regression test for bug #119005 +character*2 :: ary4 +!CHECK: DATA ary4/"cd"/ +data ary4/"abcdef"(3:4)/ +end +