[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
================
@@ -4835,6 +4950,126 @@ void ArgumentAnalyzer::Analyze(
}
}
+// C1538: Each consequent-arg shall have the same declared type and kind
+// C1539: Each consequent-arg shall have the same rank or be assumed-rank
+bool ArgumentAnalyzer::CheckConsequentTypesAndRanks(
+ const ActualArgument::ConditionalArg &condArg) {
+ const Expr<SomeType> *refExpr{condArg.FirstNonNilConsequent()};
+ if (!refExpr) {
+ return true; // all .NIL.; caller checks separately
+ }
+ auto refType{refExpr->GetType()};
+ if (!refType) {
+ return true; // typeless; should have been caught earlier
+ }
+ int refRank{-1};
+ bool allSameRank{true};
+ bool hasAssumedRank{false};
+ bool hasNonAssumedRank{false};
+
+ // Check a single consequent against the reference type and rank
+ auto checkOne{[&](const ActualArgument::ConditionalArg::Consequent &cons)
+ -> bool {
+ if (!cons) {
+ return true; // .NIL. is ok
+ }
+ auto thisType{cons->value().GetType()};
+ if (thisType) {
+ if (refType->category() != thisType->category() ||
+ (refType->category() != TypeCategory::Derived &&
+ refType->kind() != thisType->kind())) {
+ context_.Say(
+ "All consequent-args in a conditional argument must have the same type and kind; have %s and %s"_err_en_US,
+ refType->AsFortran(), thisType->AsFortran());
+ return false;
+ }
+ if (refType->category() == TypeCategory::Derived) {
+ // C1538: same declared type required. Unlimited polymorphic
+ // (CLASS(*)) and assumed type (TYPE(*)) have no declared type,
+ // so mixing them with other types is invalid.
+ if (refType->IsUnlimitedPolymorphic() !=
+ thisType->IsUnlimitedPolymorphic()) {
+ context_.Say(
+ "All consequent-args in a conditional argument must have the same type and kind; have %s and %s"_err_en_US,
+ refType->AsFortran(), thisType->AsFortran());
+ return false;
+ }
+ if (refType->IsAssumedType() != thisType->IsAssumedType()) {
+ context_.Say(
+ "All consequent-args in a conditional argument must have the same type and kind; have %s and %s"_err_en_US,
+ refType->AsFortran(), thisType->AsFortran());
+ return false;
+ }
+ if (!refType->IsUnlimitedPolymorphic() && !refType->IsAssumedType()) {
----------------
jeanPerier wrote:
nit: AssumedType implies IsUnlimitedPolymorphic by definition, so `!IsUnlimitedPolymorphic` implies `!AssumedType` and is enough here.
https://github.com/llvm/llvm-project/pull/195345
More information about the flang-commits
mailing list