[OpenMP] Show error if VLAs are not supported
Some target devices (e.g. Nvidia GPUs) don't support dynamic stack
allocation and hence no VLAs. Print errors with description instead
of failing in the backend or generating code that doesn't work.
This patch handles explicit uses of VLAs (local variable in target
or declare target region) or implicitly generated (private) VLAs
for reductions on VLAs or on array sections with non-constant size.
Differential Revision: https://reviews.llvm.org/D39505
llvm-svn: 318601
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 0a48133..0f349bb 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1303,6 +1303,17 @@
return DSAStack->getNestingLevel();
}
+bool Sema::isInOpenMPTargetExecutionDirective() const {
+ return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
+ !DSAStack->isClauseParsingMode()) ||
+ DSAStack->hasDirective(
+ [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
+ SourceLocation) -> bool {
+ return isOpenMPTargetExecutionDirective(K);
+ },
+ false);
+}
+
VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) {
assert(LangOpts.OpenMP && "OpenMP is not allowed");
D = getCanonicalDecl(D);
@@ -1315,18 +1326,8 @@
// inserted here once support for 'declare target' is added.
//
auto *VD = dyn_cast<VarDecl>(D);
- if (VD && !VD->hasLocalStorage()) {
- if (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
- !DSAStack->isClauseParsingMode())
- return VD;
- if (DSAStack->hasDirective(
- [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
- SourceLocation) -> bool {
- return isOpenMPTargetExecutionDirective(K);
- },
- false))
- return VD;
- }
+ if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective())
+ return VD;
if (DSAStack->getCurrentDirective() != OMPD_unknown &&
(!DSAStack->isClauseParsingMode() ||
@@ -9812,6 +9813,12 @@
if ((OASE && !ConstantLengthOASE) ||
(!OASE && !ASE &&
D->getType().getNonReferenceType()->isVariablyModifiedType())) {
+ if (!Context.getTargetInfo().isVLASupported() &&
+ S.shouldDiagnoseTargetSupportFromOpenMP()) {
+ S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
+ S.Diag(ELoc, diag::note_vla_unsupported);
+ continue;
+ }
// For arrays/array sections only:
// Create pseudo array type for private copy. The size for this array will
// be generated during codegen.