[flang-commits] [flang] [flang][Lower] Implement lowering for new expression kind used in explicit-shape-bounds-spec (PR #215403)

via flang-commits flang-commits at lists.llvm.org
Sun Sep 20 12:39:54 PDT 2026


================
@@ -1585,15 +1585,230 @@ Expr<TypeParamInquiry::Result> FoldOperation(
   return AsExpr(std::move(inquiry));
 }
 
+// Extract element [dim] (0-based, array-element order) from a rank-1 integer
+// array expression as a scalar, distributing the extraction through kind
+// conversions, elementwise integer operations, and elemental intrinsic calls,
+// and indexing array sections and array constructors (including implied-dos),
+// so the result is genuine Fortran that round-trips through module files.
+// Returns std::nullopt when a leaf cannot be reduced (e.g. a user function
+// reference), so the caller keeps the RankOneBoundElement unchanged.
+template <int KIND>
+static std::optional<Expr<Type<TypeCategory::Integer, KIND>>>
+ExtractRankOneElement(FoldingContext &context,
+    const Expr<Type<TypeCategory::Integer, KIND>> &base, int dim) {
+  using T = Type<TypeCategory::Integer, KIND>;
+  if (base.Rank() == 0) {
+    return base; // a scalar operand contributes itself to every element
+  }
+  return common::visit(
+      [&](const auto &y) -> std::optional<Expr<T>> {
+        using Ty = std::decay_t<decltype(y)>;
+        if constexpr (std::is_same_v<Ty, Constant<T>>) {
+          ConstantSubscripts at{y.lbounds()};
+          at[0] = y.lbounds()[0] + dim;
+          return Expr<T>{Constant<T>{y.At(at)}};
+        } else if constexpr (std::is_same_v<Ty, Designator<T>>) {
+          if (auto named{ExtractNamedEntity(Expr<T>{y})}) {
+            // Whole array or component: element [dim] is base(lbound+dim).
+            if (MaybeExtentExpr lb{GetLBOUND(context, *named, /*dim=*/0)}) {
+              Expr<SubscriptInteger> at{
+                  Fold(context, std::move(*lb) + Expr<SubscriptInteger>{dim})};
+              std::vector<Subscript> ss;
+              ss.emplace_back(std::move(at));
+              ArrayRef ref{std::move(*named), std::move(ss)};
----------------
MattPD wrote:

Confirmed: Separate compilation now preserves rank one for `b` in the array-parent component case.

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


More information about the flang-commits mailing list