diff --git a/flang/docs/OpenACC.md b/flang/docs/OpenACC.md --- a/flang/docs/OpenACC.md +++ b/flang/docs/OpenACC.md @@ -17,3 +17,5 @@ * The end directive for combined construct can omit the `loop` keyword. * An `!$acc routine` with no parallelism clause is treated as if the `seq` clause was present. +* The restriction on `!$acc data` required clauses is emitted as a portability + warning instead of an error as other compiler accepts it. diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -1937,6 +1937,9 @@ addOperands(operands, operandSegments, waitOperands); addOperands(operands, operandSegments, dataClauseOperands); + if (dataClauseOperands.empty() && !hasDefaultNone && !hasDefaultPresent) + return; + auto dataOp = createRegionOp( builder, currentLocation, operands, operandSegments); diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp --- a/flang/lib/Semantics/check-acc-structure.cpp +++ b/flang/lib/Semantics/check-acc-structure.cpp @@ -147,8 +147,9 @@ CheckNoBranching(block, GetContext().directive, blockDir.source); break; case llvm::acc::Directive::ACCD_data: - // Restriction - line 1249-1250 - CheckRequireAtLeastOneOf(); + // Restriction - 2.6.5 pt 1 + // Only a warning is emitted here for portability reason. + CheckRequireAtLeastOneOf(/*warnInsteadOfError=*/true); // Restriction is not formally in the specification but all compilers emit // an error and it is likely to be omitted from the spec. CheckNoBranching(block, GetContext().directive, blockDir.source); diff --git a/flang/lib/Semantics/check-directive-structure.h b/flang/lib/Semantics/check-directive-structure.h --- a/flang/lib/Semantics/check-directive-structure.h +++ b/flang/lib/Semantics/check-directive-structure.h @@ -331,7 +331,7 @@ // Check that only clauses in set are after the specific clauses. void CheckOnlyAllowedAfter(C clause, common::EnumSet set); - void CheckRequireAtLeastOneOf(); + void CheckRequireAtLeastOneOf(bool warnInsteadOfError = false); void CheckAllowed(C clause); @@ -422,7 +422,7 @@ // directive. template void DirectiveStructureChecker::CheckRequireAtLeastOneOf() { + ClauseEnumSize>::CheckRequireAtLeastOneOf(bool warnInsteadOfError) { if (GetContext().requiredClauses.empty()) return; for (auto cl : GetContext().actualClauses) { @@ -430,10 +430,16 @@ return; } // No clause matched in the actual clauses list - context_.Say(GetContext().directiveSource, - "At least one of %s clause must appear on the %s directive"_err_en_US, - ClauseSetToString(GetContext().requiredClauses), - ContextDirectiveAsFortran()); + if (warnInsteadOfError) + context_.Say(GetContext().directiveSource, + "At least one of %s clause should appear on the %s directive"_port_en_US, + ClauseSetToString(GetContext().requiredClauses), + ContextDirectiveAsFortran()); + else + context_.Say(GetContext().directiveSource, + "At least one of %s clause must appear on the %s directive"_err_en_US, + ClauseSetToString(GetContext().requiredClauses), + ContextDirectiveAsFortran()); } template diff --git a/flang/test/Lower/OpenACC/acc-data.f90 b/flang/test/Lower/OpenACC/acc-data.f90 --- a/flang/test/Lower/OpenACC/acc-data.f90 +++ b/flang/test/Lower/OpenACC/acc-data.f90 @@ -188,5 +188,9 @@ ! CHECK: acc.terminator ! CHECK: } attributes {defaultAttr = #acc} + !$acc data + !$acc end data +! CHECK-NOT: acc.data + end subroutine acc_data diff --git a/flang/test/Semantics/OpenACC/acc-data.f90 b/flang/test/Semantics/OpenACC/acc-data.f90 --- a/flang/test/Semantics/OpenACC/acc-data.f90 +++ b/flang/test/Semantics/OpenACC/acc-data.f90 @@ -132,7 +132,7 @@ !ERROR: At least one of COPYOUT, DELETE, DETACH clause must appear on the EXIT DATA directive !$acc exit data - !ERROR: At least one of ATTACH, COPY, COPYIN, COPYOUT, CREATE, DEFAULT, DEVICEPTR, NO_CREATE, PRESENT clause must appear on the DATA directive + !PORTABILITY: At least one of ATTACH, COPY, COPYIN, COPYOUT, CREATE, DEFAULT, DEVICEPTR, NO_CREATE, PRESENT clause should appear on the DATA directive !$acc data !$acc end data