[flang-commits] [flang] [flang] Implement conditional expressions parser/semantics (F2023) (PR #186489)
Caroline Newcombe via flang-commits
flang-commits at lists.llvm.org
Mon Apr 6 08:27:25 PDT 2026
================
@@ -3876,6 +3880,111 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::PercentLoc &x) {
return MakeFunctionRef(loc, ActualArguments{std::move(*arg)});
}
+MaybeExpr ExpressionAnalyzer::Analyze(const parser::ConditionalExpr &x) {
+ // Chained else-expressions recurse automatically through Analyze(Expr).
+ MaybeExpr condExpr{Analyze(std::get<0>(x.t))};
+ MaybeExpr thenExpr{Analyze(std::get<1>(x.t).value())};
+ MaybeExpr elseExpr{Analyze(std::get<2>(x.t).value())};
+ if (!condExpr || !thenExpr || !elseExpr) {
+ return std::nullopt;
+ }
+ if (std::holds_alternative<BOZLiteralConstant>(thenExpr->u) ||
+ std::holds_alternative<BOZLiteralConstant>(elseExpr->u)) {
+ Say("BOZ literal constant in conditional expression must have explicit "
+ "type (e.g., INT(z'FF'), REAL(z'3F800000'))"_err_en_US);
+ return std::nullopt;
+ }
+ if (IsNullPointerOrAllocatable(&*thenExpr) ||
+ IsNullPointerOrAllocatable(&*elseExpr)) {
+ Say("NULL() not allowed in a conditional expression"_err_en_US);
+ return std::nullopt;
+ }
+ if (semantics::IsAssumedRank(*thenExpr) ||
+ semantics::IsAssumedRank(*elseExpr)) {
+ Say("An assumed-rank dummy argument may not be used as a value in a conditional expression"_err_en_US);
+ return std::nullopt;
+ }
+ if ((ExtractDataRef(thenExpr) &&
+ ExtractCoarrayRef(*ExtractDataRef(thenExpr))) ||
+ (ExtractDataRef(elseExpr) &&
+ ExtractCoarrayRef(*ExtractDataRef(elseExpr)))) {
+ Say("Conditional expression values may not be coindexed"_err_en_US);
+ return std::nullopt;
+ }
+ // F2023 C1004: then-expr and else-expr must have the same declared type,
+ // kind type parameters, and rank.
+ if (thenExpr->Rank() != elseExpr->Rank()) {
+ Say("All values in conditional expression must have the same rank; have rank %d and %d"_err_en_US,
+ thenExpr->Rank(), elseExpr->Rank());
+ return std::nullopt;
+ }
+ const std::optional<DynamicType> thenType{thenExpr->GetType()};
+ const std::optional<DynamicType> elseType{elseExpr->GetType()};
+ if (!thenType || !elseType) {
+ Say("Cannot determine type of conditional expression"_err_en_US);
+ return std::nullopt;
+ }
+ const TypeCategory thenCat{thenType->category()};
+ const TypeCategory elseCat{elseType->category()};
+ if (thenCat != elseCat ||
+ (thenCat != TypeCategory::Derived &&
+ thenType->kind() != elseType->kind())) {
+ Say("All values in conditional expression must have the same type and kind; have %s and %s"_err_en_US,
+ thenType->AsFortran(), elseType->AsFortran());
+ return std::nullopt;
+ }
+ if (thenCat == TypeCategory::Derived &&
+ (thenType->IsPolymorphic() || elseType->IsPolymorphic())) {
+ Say("Conditional expressions with polymorphic types (CLASS) are not yet supported"_err_en_US);
----------------
cenewcombe wrote:
Done ✔️
https://github.com/llvm/llvm-project/pull/186489
More information about the flang-commits
mailing list