[flang-commits] [flang] [flang][Parser] Allow constant expressions in data statement constants (PR #224707)

via flang-commits flang-commits at lists.llvm.org
Fri Sep 18 12:01:17 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-parser

Author: Daniel Chen (DanielCChen)

<details>
<summary>Changes</summary>

Consider the following code
```
integer :: int1 /2**2/
integer :: int2 = 2**2
integer :: int3 /2/
print*, int1
print*, int2
print*, int3
end
```

Flang currently flag an error as:

```
error: Could not parse aa.f
aa.f:1:17: error: expected end of statement
  integer :: int1 /2**2/
                  ^
```

However, the next two line of initialization work fine.
             
This PR is to extend `DataStmtConstant` to accept general expressions (e.g. `2**2` in
slash initializations) and disambiguate repeat factor `'*'` from exponent
operator `'**'`.

Assisted-by: IBM Bob.

---
Full diff: https://github.com/llvm/llvm-project/pull/224707.diff


3 Files Affected:

- (modified) flang/include/flang/Parser/parse-tree.h (+1-1) 
- (modified) flang/lib/Parser/Fortran-parsers.cpp (+7-5) 
- (modified) flang/test/Parser/lit-substr-data.f90 (+9) 


``````````diff
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 3e9a035d0bfee5..e03924c824b4b4 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -1516,7 +1516,7 @@ struct DataStmtConstant {
   std::variant<common::Indirection<CharLiteralConstantSubstring>,
       LiteralConstant, SignedIntLiteralConstant, SignedRealLiteralConstant,
       SignedComplexLiteralConstant, NullInit, common::Indirection<Designator>,
-      StructureConstructor, UnsignedLiteralConstant>
+      StructureConstructor, UnsignedLiteralConstant, common::Indirection<Expr>>
       u;
 };
 
diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index a20983e095d185..a422d1b2b936b1 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -958,7 +958,8 @@ TYPE_PARSER(construct<DataIDoObject>(scalar(indirect(designator))) ||
 
 // R843 data-stmt-value -> [data-stmt-repeat *] data-stmt-constant
 TYPE_PARSER(construct<DataStmtValue>(
-    maybe(Parser<DataStmtRepeat>{} / "*"), Parser<DataStmtConstant>{}))
+    maybe(Parser<DataStmtRepeat>{} / ("*"_tok / !"*"_tok)),
+    Parser<DataStmtConstant>{}))
 
 // R847 constant-subobject -> designator
 // R846 int-constant-subobject -> constant-subobject
@@ -986,15 +987,16 @@ TYPE_PARSER(construct<DataStmtRepeat>(intLiteralConstant) ||
 // first to avoid a partial match with a literal constant.
 TYPE_PARSER(sourced(first(
     construct<DataStmtConstant>(indirect(charLiteralConstantSubstring)),
-    construct<DataStmtConstant>(literalConstant),
-    construct<DataStmtConstant>(signedRealLiteralConstant),
-    construct<DataStmtConstant>(signedIntLiteralConstant),
+    construct<DataStmtConstant>(literalConstant / !"**"_tok),
+    construct<DataStmtConstant>(signedRealLiteralConstant / !"**"_tok),
+    construct<DataStmtConstant>(signedIntLiteralConstant / !"**"_tok),
     extension<LanguageFeature::SignedComplexLiteral>(
         "nonstandard usage: signed COMPLEX literal"_port_en_US,
         construct<DataStmtConstant>(Parser<SignedComplexLiteralConstant>{})),
     construct<DataStmtConstant>(nullInit),
     construct<DataStmtConstant>(indirect(designator) / !"("_tok),
-    construct<DataStmtConstant>(Parser<StructureConstructor>{}))))
+    construct<DataStmtConstant>(Parser<StructureConstructor>{}),
+    construct<DataStmtConstant>(indirect(expr)))))
 
 // R848 dimension-stmt ->
 //        DIMENSION [::] array-name ( array-spec )
diff --git a/flang/test/Parser/lit-substr-data.f90 b/flang/test/Parser/lit-substr-data.f90
index 7eed616a1ee2ec..58dfe758aa1378 100644
--- a/flang/test/Parser/lit-substr-data.f90
+++ b/flang/test/Parser/lit-substr-data.f90
@@ -5,3 +5,12 @@
 data ary4/"abcdef"(3:4)/
 end
 
+! Regression test: constant expressions (not just literals) must be accepted
+! in old-style slash initialization.
+subroutine test_slash_init_const_expr
+!CHECK: INTEGER int1/4_4/
+  integer :: int1 /2**2/
+!CHECK: INTEGER int2/2_4/
+  integer :: int2 /2/
+  print*, int1, int2
+end subroutine

``````````

</details>


https://github.com/llvm/llvm-project/pull/224707


More information about the flang-commits mailing list