diff --git a/flang/include/flang/Parser/tools.h b/flang/include/flang/Parser/tools.h index f1ead11734fa0..447bccd5d35a6 100644 --- a/flang/include/flang/Parser/tools.h +++ b/flang/include/flang/Parser/tools.h @@ -250,5 +250,8 @@ template std::optional GetLastSource(A &x) { return GetSourceHelper::GetSource(const_cast(x)); } +// Checks whether the assignment statement has a single variable on the RHS. +bool CheckForSingleVariableOnRHS(const AssignmentStmt &); + } // namespace Fortran::parser #endif // FORTRAN_PARSER_TOOLS_H_ diff --git a/flang/include/flang/Semantics/tools.h b/flang/include/flang/Semantics/tools.h index 3839bc1d2a215..4b2bb4fa167f8 100644 --- a/flang/include/flang/Semantics/tools.h +++ b/flang/include/flang/Semantics/tools.h @@ -753,29 +753,7 @@ std::string GetCommonBlockObjectName(const Symbol &, bool underscoring); // Check for ambiguous USE associations bool HadUseError(SemanticsContext &, SourceName at, const Symbol *); -/// Checks if the assignment statement has a single variable on the RHS. -inline bool checkForSingleVariableOnRHS( - const Fortran::parser::AssignmentStmt &assignmentStmt) { - const Fortran::parser::Expr &expr{ - std::get(assignmentStmt.t)}; - const Fortran::common::Indirection *designator = - std::get_if>( - &expr.u); - return designator != nullptr; -} - -/// Checks if the symbol on the LHS is present in the RHS expression. -inline bool checkForSymbolMatch(const Fortran::semantics::SomeExpr *lhs, - const Fortran::semantics::SomeExpr *rhs) { - auto lhsSyms{Fortran::evaluate::GetSymbolVector(*lhs)}; - const Fortran::semantics::Symbol &lhsSymbol{*lhsSyms.front()}; - for (const Fortran::semantics::Symbol &symbol : - Fortran::evaluate::GetSymbolVector(*rhs)) { - if (lhsSymbol == symbol) { - return true; - } - } - return false; -} +// Checks whether the symbol on the LHS is present in the RHS expression. +bool CheckForSymbolMatch(const SomeExpr *lhs, const SomeExpr *rhs); } // namespace Fortran::semantics #endif // FORTRAN_SEMANTICS_TOOLS_H_ diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 02dba22c29c7f..c10e1777614cd 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -653,8 +653,8 @@ void genAtomicCapture(Fortran::lower::AbstractConverter &converter, firOpBuilder.createBlock(&(atomicCaptureOp->getRegion(0))); mlir::Block &block = atomicCaptureOp->getRegion(0).back(); firOpBuilder.setInsertionPointToStart(&block); - if (Fortran::semantics::checkForSingleVariableOnRHS(stmt1)) { - if (Fortran::semantics::checkForSymbolMatch( + if (Fortran::parser::CheckForSingleVariableOnRHS(stmt1)) { + if (Fortran::semantics::CheckForSymbolMatch( Fortran::semantics::GetExpr(stmt2Var), Fortran::semantics::GetExpr(stmt2Expr))) { // Atomic capture construct is of the form [capture-stmt, update-stmt] diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index ddb08f74b3841..e07f33671e728 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -3199,8 +3199,8 @@ static void genAtomicCapture(lower::AbstractConverter &converter, firOpBuilder.createBlock(&(atomicCaptureOp->getRegion(0))); mlir::Block &block = atomicCaptureOp->getRegion(0).back(); firOpBuilder.setInsertionPointToStart(&block); - if (semantics::checkForSingleVariableOnRHS(stmt1)) { - if (semantics::checkForSymbolMatch(semantics::GetExpr(stmt2Var), + if (parser::CheckForSingleVariableOnRHS(stmt1)) { + if (semantics::CheckForSymbolMatch(semantics::GetExpr(stmt2Var), semantics::GetExpr(stmt2Expr))) { // Atomic capture construct is of the form [capture-stmt, update-stmt] const semantics::SomeExpr &fromExpr = *semantics::GetExpr(stmt1Expr); diff --git a/flang/lib/Parser/tools.cpp b/flang/lib/Parser/tools.cpp index 6e5f1ed2fc66f..264ca520f38b8 100644 --- a/flang/lib/Parser/tools.cpp +++ b/flang/lib/Parser/tools.cpp @@ -174,4 +174,9 @@ const CoindexedNamedObject *GetCoindexedNamedObject( }, allocateObject.u); } + +bool CheckForSingleVariableOnRHS(const AssignmentStmt &assignmentStmt) { + return Unwrap(std::get(assignmentStmt.t)) != nullptr; +} + } // namespace Fortran::parser diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index bda0d62829506..ae5dca1b95f6e 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -2922,9 +2922,9 @@ void OmpStructureChecker::CheckAtomicCaptureConstruct( const auto *e2 = GetExpr(context_, stmt2Expr); if (e1 && v1 && e2 && v2) { - if (semantics::checkForSingleVariableOnRHS(stmt1)) { + if (parser::CheckForSingleVariableOnRHS(stmt1)) { CheckAtomicCaptureStmt(stmt1); - if (semantics::checkForSymbolMatch(v2, e2)) { + if (CheckForSymbolMatch(v2, e2)) { // ATOMIC CAPTURE construct is of the form [capture-stmt, update-stmt] CheckAtomicUpdateStmt(stmt2); } else { @@ -2936,8 +2936,8 @@ void OmpStructureChecker::CheckAtomicCaptureConstruct( "Captured variable/array element/derived-type component %s expected to be assigned in the second statement of ATOMIC CAPTURE construct"_err_en_US, stmt1Expr.source); } - } else if (semantics::checkForSymbolMatch(v1, e1) && - semantics::checkForSingleVariableOnRHS(stmt2)) { + } else if (CheckForSymbolMatch(v1, e1) && + parser::CheckForSingleVariableOnRHS(stmt2)) { // ATOMIC CAPTURE construct is of the form [update-stmt, capture-stmt] CheckAtomicUpdateStmt(stmt1); CheckAtomicCaptureStmt(stmt2); diff --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp index 1d1e3ac044166..ac69e6ff5cb79 100644 --- a/flang/lib/Semantics/tools.cpp +++ b/flang/lib/Semantics/tools.cpp @@ -1756,4 +1756,18 @@ bool HadUseError( } } +bool CheckForSymbolMatch(const SomeExpr *lhs, const SomeExpr *rhs) { + if (lhs && rhs) { + if (SymbolVector lhsSymbols{evaluate::GetSymbolVector(*lhs)}; + !lhsSymbols.empty()) { + const Symbol &first{*lhsSymbols.front()}; + for (const Symbol &symbol : evaluate::GetSymbolVector(*rhs)) { + if (first == symbol) { + return true; + } + } + } + } + return false; +} } // namespace Fortran::semantics