diff --git a/flang/lib/evaluate/expression.cc b/flang/lib/evaluate/expression.cc index 048839fdf9be..d59aae8bdae8 100644 --- a/flang/lib/evaluate/expression.cc +++ b/flang/lib/evaluate/expression.cc @@ -171,10 +171,6 @@ StructureConstructor &StructureConstructor::Add( GenericExprWrapper::~GenericExprWrapper() {} -bool GenericExprWrapper::operator==(const GenericExprWrapper &that) const { - return v == that.v; -} - GenericAssignmentWrapper::~GenericAssignmentWrapper() {} template int Expr>::GetKind() const { diff --git a/flang/lib/evaluate/expression.h b/flang/lib/evaluate/expression.h index 560f70a84356..7b3cb169da4d 100644 --- a/flang/lib/evaluate/expression.h +++ b/flang/lib/evaluate/expression.h @@ -872,19 +872,19 @@ public: // This wrapper class is used, by means of a forward reference with // an owning pointer, to cache analyzed expressions in parse tree nodes. -// v is nullopt if an error occurred during expression analysis. struct GenericExprWrapper { - GenericExprWrapper(std::optional> &&x) : v{std::move(x)} {} + GenericExprWrapper() {} + explicit GenericExprWrapper(std::optional> &&x) + : v{std::move(x)} {} ~GenericExprWrapper(); - bool operator==(const GenericExprWrapper &) const; - std::optional> v; + std::optional> v; // vacant if error }; // Like GenericExprWrapper but for analyzed assignments struct GenericAssignmentWrapper { - GenericAssignmentWrapper(std::optional &&x) : v{std::move(x)} {} + explicit GenericAssignmentWrapper(Assignment &&x) : v{std::move(x)} {} ~GenericAssignmentWrapper(); - std::optional v; + Assignment v; }; FOR_EACH_CATEGORY_TYPE(extern template class Expr, ) diff --git a/flang/lib/parser/unparse.cc b/flang/lib/parser/unparse.cc index 606d4e66c0e8..f68856edb7ea 100644 --- a/flang/lib/parser/unparse.cc +++ b/flang/lib/parser/unparse.cc @@ -803,7 +803,7 @@ public: // R1001 - R1022 bool Pre(const Expr &x) { - if (asFortran_ && x.typedExpr.get()) { + if (asFortran_ && x.typedExpr) { // Format the expression representation from semantics asFortran_->expr(out_, *x.typedExpr); return false; diff --git a/flang/lib/semantics/expression.cc b/flang/lib/semantics/expression.cc index 12004817c650..cb60f4fa52f7 100644 --- a/flang/lib/semantics/expression.cc +++ b/flang/lib/semantics/expression.cc @@ -2260,7 +2260,7 @@ static void FixMisparsedFunctionReference( // Common handling of parser::Expr and parser::Variable template MaybeExpr ExpressionAnalyzer::ExprOrVariable(const PARSED &x) { - if (!x.typedExpr) { // not yet analyzed + if (!x.typedExpr) { FixMisparsedFunctionReference(context_, x.u); MaybeExpr result; if constexpr (std::is_same_v) { diff --git a/flang/lib/semantics/expression.h b/flang/lib/semantics/expression.h index 1631ec372fcb..f016db0a4df9 100644 --- a/flang/lib/semantics/expression.h +++ b/flang/lib/semantics/expression.h @@ -89,8 +89,10 @@ namespace Fortran::evaluate { class IntrinsicProcTable; struct SetExprHelper { - SetExprHelper(GenericExprWrapper &&expr) : expr_{std::move(expr)} {} - void Set(parser::Expr::TypedExpr &x) { x->v = std::move(expr_.v); } + explicit SetExprHelper(GenericExprWrapper &&expr) : expr_{std::move(expr)} {} + void Set(parser::Expr::TypedExpr &x) { + x.reset(new GenericExprWrapper{std::move(expr_)}); + } void Set(const parser::Expr &x) { Set(x.typedExpr); } void Set(const parser::Variable &x) { Set(x.typedExpr); } template void Set(const common::Indirection &x) { @@ -107,13 +109,12 @@ struct SetExprHelper { GenericExprWrapper expr_; }; -// Set the typedExpr data member to std::nullopt to indicate an error template void ResetExpr(const T &x) { - SetExprHelper{GenericExprWrapper{std::nullopt}}.Set(x); + SetExprHelper{GenericExprWrapper{/* error indicator */}}.Set(x); } -template void SetExpr(const T &x, GenericExprWrapper &&expr) { - SetExprHelper{std::move(expr)}.Set(x); +template void SetExpr(const T &x, Expr &&expr) { + SetExprHelper{GenericExprWrapper{std::move(expr)}}.Set(x); } class ExpressionAnalyzer { @@ -197,7 +198,7 @@ public: return std::nullopt; } else { // Save folded expression for later use - SetExpr(x, common::Clone(result)); + SetExpr(x, common::Clone(*result)); } } return result; diff --git a/flang/lib/semantics/tools.cc b/flang/lib/semantics/tools.cc index 90878d6db2ec..7548969dd1e3 100644 --- a/flang/lib/semantics/tools.cc +++ b/flang/lib/semantics/tools.cc @@ -393,7 +393,7 @@ bool ExprTypeKindIsDefault( const evaluate::Assignment *GetAssignment(const parser::AssignmentStmt &x) { const auto &typed{x.typedAssignment}; - return typed && typed->v ? &*typed->v : nullptr; + return typed ? &typed->v : nullptr; } const Symbol *FindInterface(const Symbol &symbol) { diff --git a/flang/lib/semantics/tools.h b/flang/lib/semantics/tools.h index 9bfb86a3de3e..2c545ccf5d9b 100644 --- a/flang/lib/semantics/tools.h +++ b/flang/lib/semantics/tools.h @@ -233,7 +233,7 @@ bool ExprTypeKindIsDefault( struct GetExprHelper { const SomeExpr *Get(const parser::Expr::TypedExpr &x) { CHECK(x); - return x->v ? &*x->v : nullptr; + return x && x->v ? &*x->v : nullptr; } const SomeExpr *Get(const parser::Expr &x) { return Get(x.typedExpr); } const SomeExpr *Get(const parser::Variable &x) { return Get(x.typedExpr); } diff --git a/flang/tools/f18/f18.cc b/flang/tools/f18/f18.cc index d965758331cc..ba5176588253 100644 --- a/flang/tools/f18/f18.cc +++ b/flang/tools/f18/f18.cc @@ -292,26 +292,22 @@ std::string CompileFortran(std::string path, Fortran::parser::Options options, Fortran::parser::AnalyzedObjectsAsFortran asFortran{ [](std::ostream &o, const Fortran::evaluate::GenericExprWrapper &x) { if (x.v) { - o << *x.v; + x.v->AsFortran(o); } else { o << "(bad expression)"; } }, [](std::ostream &o, const Fortran::evaluate::GenericAssignmentWrapper &x) { - if (x.v) { - std::visit( - Fortran::common::visitors{ - [&](const Fortran::evaluate::Assignment::IntrinsicAssignment - &y) { y.rhs.AsFortran(y.lhs.AsFortran(o) << '='); }, - [&](const Fortran::evaluate::ProcedureRef &y) { - y.AsFortran(o << "CALL "); - }, - }, - x.v->u); - } else { - o << "(bad assignment)"; - } + std::visit( + Fortran::common::visitors{ + [&](const Fortran::evaluate::Assignment::IntrinsicAssignment + &y) { y.rhs.AsFortran(y.lhs.AsFortran(o) << '='); }, + [&](const Fortran::evaluate::ProcedureRef &y) { + y.AsFortran(o << "CALL "); + }, + }, + x.v.u); }, [](std::ostream &o, const Fortran::evaluate::ProcedureRef &x) { x.AsFortran(o << "CALL ");