[Flang][OpenMP] Add semantic check for OpenMP Private, Firstprivate and Lastprivate clauses.
OpenMP 4.5 - Variables that appear in expressions for statement function definitions may not appear in OpenMP Private, Firstprivate or Lastprivate clauses. Test case : omp-private03.f90 Reviewed By: kiranchandramohan Differential Revision: https://reviews.llvm.org/D93213
This commit is contained in:
parent
893c84d71c
commit
a2ca6bbda6
|
@ -232,6 +232,18 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Pre(const parser::StmtFunctionStmt &x) {
|
||||
const auto &parsedExpr{std::get<parser::Scalar<parser::Expr>>(x.t)};
|
||||
if (const auto *expr{GetExpr(parsedExpr)}) {
|
||||
for (const Symbol &symbol : evaluate::CollectSymbols(*expr)) {
|
||||
if (!IsStmtFunctionDummy(symbol)) {
|
||||
stmtFunctionExprSymbols_.insert(symbol.GetUltimate());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Pre(const parser::OpenMPBlockConstruct &);
|
||||
void Post(const parser::OpenMPBlockConstruct &);
|
||||
|
||||
|
@ -342,6 +354,7 @@ private:
|
|||
|
||||
std::vector<const parser::Name *> allocateNames_; // on one directive
|
||||
SymbolSet privateDataSharingAttributeObjects_; // on one directive
|
||||
SymbolSet stmtFunctionExprSymbols_;
|
||||
|
||||
void AddAllocateName(const parser::Name *&object) {
|
||||
allocateNames_.push_back(object);
|
||||
|
@ -377,7 +390,7 @@ private:
|
|||
const parser::Name &, const Symbol &, Symbol::Flag);
|
||||
|
||||
void CheckAssocLoopLevel(std::int64_t level, const parser::OmpClause *clause);
|
||||
void CheckObjectInNamelist(
|
||||
void CheckPrivateDSAObject(
|
||||
const parser::Name &, const Symbol &, Symbol::Flag);
|
||||
};
|
||||
|
||||
|
@ -1163,7 +1176,7 @@ void OmpAttributeVisitor::ResolveOmpObject(
|
|||
CheckMultipleAppearances(*name, *symbol, ompFlag);
|
||||
}
|
||||
if (privateDataSharingAttributeFlags.test(ompFlag)) {
|
||||
CheckObjectInNamelist(*name, *symbol, ompFlag);
|
||||
CheckPrivateDSAObject(*name, *symbol, ompFlag);
|
||||
}
|
||||
|
||||
if (ompFlag == Symbol::Flag::OmpAllocate) {
|
||||
|
@ -1317,18 +1330,28 @@ void OmpAttributeVisitor::CheckDataCopyingClause(
|
|||
}
|
||||
}
|
||||
|
||||
void OmpAttributeVisitor::CheckObjectInNamelist(
|
||||
void OmpAttributeVisitor::CheckPrivateDSAObject(
|
||||
const parser::Name &name, const Symbol &symbol, Symbol::Flag ompFlag) {
|
||||
if (symbol.GetUltimate().test(Symbol::Flag::InNamelist)) {
|
||||
llvm::StringRef clauseName{"PRIVATE"};
|
||||
if (ompFlag == Symbol::Flag::OmpFirstPrivate)
|
||||
clauseName = "FIRSTPRIVATE";
|
||||
else if (ompFlag == Symbol::Flag::OmpLastPrivate)
|
||||
clauseName = "LASTPRIVATE";
|
||||
const auto &ultimateSymbol{symbol.GetUltimate()};
|
||||
llvm::StringRef clauseName{"PRIVATE"};
|
||||
if (ompFlag == Symbol::Flag::OmpFirstPrivate)
|
||||
clauseName = "FIRSTPRIVATE";
|
||||
else if (ompFlag == Symbol::Flag::OmpLastPrivate)
|
||||
clauseName = "LASTPRIVATE";
|
||||
|
||||
if (ultimateSymbol.test(Symbol::Flag::InNamelist)) {
|
||||
context_.Say(name.source,
|
||||
"Variable '%s' in NAMELIST cannot be in a %s clause"_err_en_US,
|
||||
name.ToString(), clauseName.str());
|
||||
}
|
||||
|
||||
if (stmtFunctionExprSymbols_.find(ultimateSymbol) !=
|
||||
stmtFunctionExprSymbols_.end()) {
|
||||
context_.Say(name.source,
|
||||
"Variable '%s' in STATEMENT FUNCTION expression cannot be in a "
|
||||
"%s clause"_err_en_US,
|
||||
name.ToString(), clauseName.str());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Fortran::semantics
|
||||
|
|
39
flang/test/Semantics/omp-private03.f90
Normal file
39
flang/test/Semantics/omp-private03.f90
Normal file
|
@ -0,0 +1,39 @@
|
|||
! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
|
||||
! OpenMP Version 4.5
|
||||
! Variables that appear in expressions for statement function definitions
|
||||
! may not appear in private, firstprivate or lastprivate clauses.
|
||||
|
||||
subroutine stmt_function(temp)
|
||||
|
||||
integer :: i, p, q, r
|
||||
real :: c, f, s, v, t(10)
|
||||
real, intent(in) :: temp
|
||||
|
||||
c(temp) = p * (temp - q) / r
|
||||
f(temp) = q + (temp * r/p)
|
||||
v(temp) = c(temp) + f(temp)/2 - s
|
||||
|
||||
p = 5
|
||||
q = 32
|
||||
r = 9
|
||||
|
||||
!ERROR: Variable 'p' in STATEMENT FUNCTION expression cannot be in a PRIVATE clause
|
||||
!$omp parallel private(p)
|
||||
s = c(temp)
|
||||
!$omp end parallel
|
||||
|
||||
!ERROR: Variable 's' in STATEMENT FUNCTION expression cannot be in a FIRSTPRIVATE clause
|
||||
!$omp parallel firstprivate(s)
|
||||
s = s + f(temp)
|
||||
!$omp end parallel
|
||||
|
||||
!ERROR: Variable 's' in STATEMENT FUNCTION expression cannot be in a LASTPRIVATE clause
|
||||
!$omp parallel do lastprivate(s, t)
|
||||
do i = 1, 10
|
||||
t(i) = v(temp) + i - s
|
||||
end do
|
||||
!$omp end parallel do
|
||||
|
||||
print *, t
|
||||
|
||||
end subroutine stmt_function
|
Loading…
Reference in a new issue