[OPENMP] Bugfix for processing of global variables in OpenMP regions.
Currently, if global variable is marked as a private OpenMP variable, the compiler crashes in debug version or generates incorrect code in release version. It happens because in the OpenMP region the original global variable is used instead of the generated private copy. It happens because currently globals variables are not captured in the OpenMP region.
This patch adds capturing of global variables iff private copy of the global variable must be used in the OpenMP region.
Differential Revision: http://reviews.llvm.org/D6259
llvm-svn: 224323
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 9950543..a1064d6 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -551,6 +551,19 @@
#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
+bool Sema::IsOpenMPCapturedVar(VarDecl *VD) {
+ assert(LangOpts.OpenMP && "OpenMP is not allowed");
+ if (DSAStack->getCurrentDirective() != OMPD_unknown) {
+ auto DVarPrivate = DSAStack->getTopDSA(VD, /*FromParent=*/false);
+ if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
+ return true;
+ DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(),
+ /*FromParent=*/false);
+ return DVarPrivate.CKind != OMPC_unknown;
+ }
+ return false;
+}
+
void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
@@ -4378,7 +4391,7 @@
VDInitRefExpr = DeclRefExpr::Create(
Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
/*TemplateKWLoc*/ SourceLocation(), VDInit,
- /*isEnclosingLocal*/ false, ELoc, Type,
+ /*isEnclosingLocal*/ true, ELoc, Type,
/*VK*/ VK_LValue);
VDInit->setIsUsed();
auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
@@ -4392,8 +4405,14 @@
else
VDPrivate->setInit(Result.getAs<Expr>());
} else {
- AddInitializerToDecl(VDPrivate, DefaultLvalueConversion(DE).get(),
- /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
+ AddInitializerToDecl(
+ VDPrivate, DefaultLvalueConversion(
+ DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
+ SourceLocation(), DE->getDecl(),
+ /*isEnclosingLocal=*/true,
+ DE->getExprLoc(), DE->getType(),
+ /*VK=*/VK_LValue)).get(),
+ /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
}
if (VDPrivate->isInvalidDecl()) {
if (IsImplicitClause) {