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

via flang-commits flang-commits at lists.llvm.org
Thu Jun 4 03:24:32 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);
+      }
----------------
jeanPerier wrote:

These are only a requirements inside calls to _generic_ procedure where this would lead to generic resolution ambiguities, it is otherwise allowed.
So you will need more context here, or to move this inside the generic resolution checks.

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


More information about the flang-commits mailing list