diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 2054a13bd92e7..512a44ba77da1 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1401,6 +1401,26 @@ void OmpStructureChecker::CheckTargetUpdate() { context_.Say(GetContext().directiveSource, "At least one motion-clause (TO/FROM) must be specified on TARGET UPDATE construct."_err_en_US); } + if (toClause && fromClause) { + SymbolSourceMap toSymbols, fromSymbols; + GetSymbolsInObjectList( + std::get(toClause->u).v, toSymbols); + GetSymbolsInObjectList( + std::get(fromClause->u).v, fromSymbols); + for (auto &[symbol, source] : toSymbols) { + auto fromSymbol = fromSymbols.find(symbol); + if (fromSymbol != fromSymbols.end()) { + context_.Say(source, + "A list item ('%s') can only appear in a TO or FROM clause, but not in both."_err_en_US, + symbol->name()); + context_.Say(source, "'%s' appears in the TO clause."_because_en_US, + symbol->name()); + context_.Say(fromSymbol->second, + "'%s' appears in the FROM clause."_because_en_US, + fromSymbol->first->name()); + } + } + } } void OmpStructureChecker::Enter( diff --git a/flang/test/Semantics/OpenMP/target-update01.f90 b/flang/test/Semantics/OpenMP/target-update01.f90 index a0728e52ba3d2..84dc60dcd75f5 100644 --- a/flang/test/Semantics/OpenMP/target-update01.f90 +++ b/flang/test/Semantics/OpenMP/target-update01.f90 @@ -13,4 +13,9 @@ subroutine foo(x) !ERROR: At most one NOWAIT clause can appear on the TARGET UPDATE directive !$omp target update to(x) nowait nowait + !ERROR: A list item ('x') can only appear in a TO or FROM clause, but not in both. + !BECAUSE: 'x' appears in the TO clause. + !BECAUSE: 'x' appears in the FROM clause. + !$omp target update to(x) from(x) + end subroutine