summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2014-12-16 07:00:22 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2014-12-16 07:00:22 +0000
commit7c818bad8a72a60b7c86c90e9eca6bfa4aef2ce7 (patch)
tree326186e7f200f32ecd1a46e44d852802455fdc0c /lib/Sema/SemaExpr.cpp
parentfa0d361201b53b2a395223e370c6377704c79b0c (diff)
[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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@224323 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp40
1 files changed, 30 insertions, 10 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index ad4fea84d3..f7756ba606 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1602,10 +1602,8 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
}
bool refersToEnclosingScope =
- (CurContext != D->getDeclContext() &&
- D->getDeclContext()->isFunctionOrMethod()) ||
- (isa<VarDecl>(D) &&
- cast<VarDecl>(D)->isInitCapture());
+ isa<VarDecl>(D) &&
+ NeedToCaptureVariable(cast<VarDecl>(D), NameInfo.getLoc());
DeclRefExpr *E;
if (isa<VarTemplateSpecializationDecl>(D)) {
@@ -11799,7 +11797,7 @@ static DeclContext *getParentOfCapturingContextOrNull(DeclContext *DC, VarDecl *
const bool Diagnose, Sema &S) {
if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC) || isLambdaCallOperator(DC))
return getLambdaAwareParentOfDeclContext(DC);
- else {
+ else if (Var->hasLocalStorage()) {
if (Diagnose)
diagnoseUncapturableValueReference(S, Loc, Var, DC);
}
@@ -12241,7 +12239,7 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc,
QualType &CaptureType,
QualType &DeclRefType,
const unsigned *const FunctionScopeIndexToStopAt) {
- bool Nested = false;
+ bool Nested = Var->isInitCapture();
DeclContext *DC = CurContext;
const unsigned MaxFunctionScopesIndex = FunctionScopeIndexToStopAt
@@ -12259,8 +12257,13 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc,
// If the variable is declared in the current context (and is not an
// init-capture), there is no need to capture it.
- if (!Var->isInitCapture() && Var->getDeclContext() == DC) return true;
- if (!Var->hasLocalStorage()) return true;
+ if (!Nested && Var->getDeclContext() == DC) return true;
+
+ // Capture global variables if it is required to use private copy of this
+ // variable.
+ bool IsGlobal = !Var->hasLocalStorage();
+ if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedVar(Var)))
+ return true;
// Walk up the stack to determine whether we can capture the variable,
// performing the "simple" checks that don't depend on type. We stop when
@@ -12281,8 +12284,17 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc,
ExprLoc,
BuildAndDiagnose,
*this);
- if (!ParentDC) return true;
-
+ // We need to check for the parent *first* because, if we *have*
+ // private-captured a global variable, we need to recursively capture it in
+ // intermediate blocks, lambdas, etc.
+ if (!ParentDC) {
+ if (IsGlobal) {
+ FunctionScopesIndex = MaxFunctionScopesIndex - 1;
+ break;
+ }
+ return true;
+ }
+
FunctionScopeInfo *FSI = FunctionScopes[FunctionScopesIndex];
CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FSI);
@@ -12508,6 +12520,14 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
DeclRefType, nullptr);
}
+bool Sema::NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc) {
+ QualType CaptureType;
+ QualType DeclRefType;
+ return !tryCaptureVariable(Var, Loc, TryCapture_Implicit, SourceLocation(),
+ /*BuildAndDiagnose=*/false, CaptureType,
+ DeclRefType, nullptr);
+}
+
QualType Sema::getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc) {
QualType CaptureType;
QualType DeclRefType;