[flang-commits] [flang] [flang] Implement conditional expressions parser/semantics (F2023) (PR #186489)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Mon Mar 16 12:19:38 PDT 2026
================
@@ -3880,6 +3880,216 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::PercentLoc &x) {
return MakeFunctionRef(loc, ActualArguments{std::move(*arg)});
}
+// Helper to detect Expr<T> types (have ::Result typedef)
+template <typename T, typename = void>
+struct HasResultType : std::false_type {};
+template <typename T>
+struct HasResultType<T, std::void_t<typename T::Result>> : std::true_type {};
+
+MaybeExpr ExpressionAnalyzer::Analyze(const parser::ConditionalExpr &x) {
+ // Analyze all branches (condition ? value pairs)
+ const auto &branches{
+ std::get<std::list<parser::ConditionalExpr::Branch>>(x.t)};
+ const auto &elseExpr{std::get<common::Indirection<parser::Expr>>(x.t)};
+ std::vector<MaybeExpr> conditions;
+ std::vector<MaybeExpr> values;
+ for (const auto &branch : branches) {
+ const auto &condition{std::get<parser::ScalarLogicalExpr>(branch.t)};
+ const auto &value{std::get<common::Indirection<parser::Expr>>(branch.t)};
+ MaybeExpr condExpr{Analyze(condition.thing.thing.value())};
+ if (!condExpr) {
+ return std::nullopt;
+ }
+ if (!std::get_if<Expr<SomeLogical>>(&condExpr->u)) {
+ if (const auto type{condExpr->GetType()}) {
+ Say("Condition in conditional expression must be LOGICAL; have %s"_err_en_US,
+ type->AsFortran());
+ } else {
+ Say("Condition in conditional expression must be LOGICAL"_err_en_US);
+ }
+ return std::nullopt;
+ }
+ if (condExpr->Rank() != 0) {
+ Say("Condition in conditional expression must be scalar; have rank %d"_err_en_US,
+ condExpr->Rank());
+ return std::nullopt;
+ }
+ conditions.push_back(std::move(condExpr));
+ MaybeExpr valExpr{Analyze(value.value())};
+ if (!valExpr) {
+ return std::nullopt;
+ }
+ if (semantics::IsAssumedRank(*valExpr)) {
+ Say("An assumed-rank dummy argument may not be used as a value in a conditional expression"_err_en_US);
+ return std::nullopt;
+ }
+ values.push_back(std::move(valExpr));
+ }
+
+ // Analyze else expression
+ MaybeExpr elseValue{Analyze(elseExpr.value())};
+ if (!elseValue) {
+ return std::nullopt;
+ }
+ if (semantics::IsAssumedRank(*elseValue)) {
+ Say("An assumed-rank dummy argument may not be used as a value in a conditional expression"_err_en_US);
+ return std::nullopt;
+ }
+ values.push_back(std::move(elseValue));
+ CHECK(values.size() == conditions.size() + 1 &&
+ "values must have exactly one more element than conditions");
+
+ // F2023 C1004: Each expr shall have the same declared type, kind type
+ // parameters, and rank Reject typeless expressions (BOZ and NULL)
----------------
klausler wrote:
missing period and newline
https://github.com/llvm/llvm-project/pull/186489
More information about the flang-commits
mailing list