[flang-commits] [flang] [flang] Add semantics support for Fortran 2023 conditional arguments (F2023 R1526-R1528) (PR #195345)

Vineet Kumar via flang-commits flang-commits at lists.llvm.org
Thu Jun 25 07:15:22 PDT 2026


================
@@ -1392,6 +1397,88 @@ static void CheckProcedureArg(evaluate::ActualArgument &arg,
   }
 }
 
+// F2023 C1540-C1543, C1545: Check conditional argument against dummy data
+// object
+static void CheckConditionalArg(
+    const evaluate::ActualArgument::ConditionalArg &condArg,
+    const characteristics::DummyDataObject &object,
+    const std::string &dummyName, parser::ContextualMessages &messages) {
+  // C1540: .NIL. shall not appear if dummy is not optional
+  if (condArg.HasNilConsequent() &&
+      !object.attrs.test(characteristics::DummyDataObject::Attr::Optional)) {
+    messages.Say(
+        ".NIL. in conditional argument associated with non-optional %s"_err_en_US,
+        dummyName);
+  }
+  // Check a single consequent for C1541, C1543, C1542
+  auto checkOneConsequent{[&](const evaluate::ActualArgument::ConditionalArg::
+                                  Consequent &cons) {
+    if (!cons) {
+      return;
+    }
+    const auto &consExpr{cons->value()};
+    // C1541: INTENT(OUT/INOUT) requires variable
+    if ((object.intent == common::Intent::Out ||
+            object.intent == common::Intent::InOut) &&
+        !evaluate::IsVariable(consExpr)) {
+      messages.Say(
+          "Each consequent-arg in conditional argument associated with INTENT(%s) %s must be a variable"_err_en_US,
+          object.intent == common::Intent::Out ? "OUT" : "IN OUT", dummyName);
+    }
+    // C1543: assumed-rank consequent-arg requires assumed-rank dummy
+    if (semantics::IsAssumedRank(consExpr) &&
+        !object.type.attrs().test(
+            characteristics::TypeAndShape::Attr::AssumedRank)) {
+      messages.Say(
+          "Assumed-rank consequent-arg in conditional argument may only be associated with assumed-rank %s"_err_en_US,
+          dummyName);
+    }
+    // C1542: coarray attribute
+    if (object.type.corank() > 0 && !evaluate::IsCoarray(consExpr)) {
+      messages.Say(
+          "Each consequent-arg in conditional argument associated with a coarray %s must be a coarray"_err_en_US,
+          dummyName);
+    }
+  }};
+  condArg.ForEachConsequent(checkOneConsequent);
+  // C1545: each consequent-arg shall have the same corank, and if any
+  // has the ALLOCATABLE or POINTER attribute, each shall have it.
+  // (Strictly applies only to generic procedure references, but enforced
+  // unconditionally for consistency.)
+  std::optional<int> firstCorank;
+  std::optional<bool> firstIsAllocatable;
+  std::optional<bool> firstIsPointer;
+  auto checkConsistency{[&](const evaluate::ActualArgument::ConditionalArg::
+                                Consequent &cons) {
+    if (!cons) {
+      return;
+    }
+    auto &consExpr{cons->value()};
+    int corank{evaluate::GetCorank(consExpr)};
+    bool isAlloc{evaluate::IsAllocatableDesignator(consExpr)};
+    bool isPtr{evaluate::IsObjectPointer(consExpr)};
+    if (!firstCorank) {
+      firstCorank = corank;
+      firstIsAllocatable = isAlloc;
+      firstIsPointer = isPtr;
+    } else {
+      if (corank != *firstCorank) {
+        messages.Say(
+            "All consequent-args in a conditional argument must have the same corank"_err_en_US);
+      }
+      if (isAlloc != *firstIsAllocatable) {
+        messages.Say(
+            "If any consequent-arg in a conditional argument has the ALLOCATABLE attribute, each must have it"_err_en_US);
+      }
+      if (isPtr != *firstIsPointer) {
+        messages.Say(
+            "If any consequent-arg in a conditional argument has the POINTER attribute, each must have it"_err_en_US);
+      }
----------------
vntkmr wrote:

If there is no strong opposition,  I would like to address this in a separate small PR. I have added a TODO comment in the code for now.

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


More information about the flang-commits mailing list