[OPENMP] Fix for LCV in simd directives in explicit clauses.

If loop control variable for simd-based directives is explicitly marked
as linear/lastprivate in clauses, codegen for such construct would
crash. Patch fixes this problem.

llvm-svn: 267101
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 0147451..97647c3 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1033,9 +1033,9 @@
   PopExpressionEvaluationContext();
 }
 
-static bool
-FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
-                         Expr *NumIterations, Sema &SemaRef, Scope *S);
+static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
+                                     Expr *NumIterations, Sema &SemaRef,
+                                     Scope *S, DSAStackTy *Stack);
 
 namespace {
 
@@ -3523,8 +3523,8 @@
   Expr *BuildPreCond(Scope *S, Expr *Cond,
                      llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
   /// \brief Build reference expression to the counter be used for codegen.
-  DeclRefExpr *
-  BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
+  DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
+                               DSAStackTy &DSA) const;
   /// \brief Build reference expression to the private counter be used for
   /// codegen.
   Expr *BuildPrivateCounterVar() const;
@@ -4063,13 +4063,17 @@
 
 /// \brief Build reference expression to the counter be used for codegen.
 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
-    llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
+    llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const {
   auto *VD = dyn_cast<VarDecl>(LCDecl);
   if (!VD) {
     VD = SemaRef.IsOpenMPCapturedDecl(LCDecl);
     auto *Ref = buildDeclRefExpr(
         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
-    Captures.insert(std::make_pair(LCRef, Ref));
+    DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false);
+    // If the loop control decl is explicitly marked as private, do not mark it
+    // as captured again.
+    if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
+      Captures.insert(std::make_pair(LCRef, Ref));
     return Ref;
   }
   return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
@@ -4283,7 +4287,7 @@
       (isOpenMPWorksharingDirective(DKind) ||
        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
       Captures);
-  ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures);
+  ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
   ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
   ResultIterSpace.CounterInit = ISC.BuildCounterInit();
   ResultIterSpace.CounterStep = ISC.BuildCounterStep();
@@ -4787,10 +4791,10 @@
       }
 
       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
-      auto *CounterVar = buildDeclRefExpr(
-          SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()),
-          IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
-          /*RefersToCapture=*/true);
+      auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
+      auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(),
+                                          IS.CounterVar->getExprLoc(),
+                                          /*RefersToCapture=*/true);
       ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
                                          IS.CounterInit, Captures);
       if (!Init.isUsable()) {
@@ -4933,7 +4937,8 @@
     for (auto C : Clauses) {
       if (auto LC = dyn_cast<OMPLinearClause>(C))
         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
-                                     B.NumIterations, *this, CurScope))
+                                     B.NumIterations, *this, CurScope,
+                                     DSAStack))
           return StmtError();
     }
   }
@@ -4986,7 +4991,8 @@
     for (auto C : Clauses) {
       if (auto LC = dyn_cast<OMPLinearClause>(C))
         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
-                                     B.NumIterations, *this, CurScope))
+                                     B.NumIterations, *this, CurScope,
+                                     DSAStack))
           return StmtError();
     }
   }
@@ -5022,7 +5028,8 @@
     for (auto C : Clauses) {
       if (auto LC = dyn_cast<OMPLinearClause>(C))
         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
-                                     B.NumIterations, *this, CurScope))
+                                     B.NumIterations, *this, CurScope,
+                                     DSAStack))
           return StmtError();
     }
   }
@@ -5238,7 +5245,8 @@
     for (auto C : Clauses) {
       if (auto LC = dyn_cast<OMPLinearClause>(C))
         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
-                                     B.NumIterations, *this, CurScope))
+                                     B.NumIterations, *this, CurScope,
+                                     DSAStack))
           return StmtError();
     }
   }
@@ -5279,7 +5287,8 @@
     for (auto C : Clauses) {
       if (auto LC = dyn_cast<OMPLinearClause>(C))
         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
-                                     B.NumIterations, *this, CurScope))
+                                     B.NumIterations, *this, CurScope,
+                                     DSAStack))
           return StmtError();
     }
   }
@@ -6251,7 +6260,8 @@
     for (auto C : Clauses) {
       if (auto LC = dyn_cast<OMPLinearClause>(C))
         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
-                                     B.NumIterations, *this, CurScope))
+                                     B.NumIterations, *this, CurScope,
+                                     DSAStack))
           return StmtError();
     }
   }
@@ -6474,7 +6484,8 @@
     for (auto C : Clauses) {
       if (auto LC = dyn_cast<OMPLinearClause>(C))
         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
-                                     B.NumIterations, *this, CurScope))
+                                     B.NumIterations, *this, CurScope,
+                                     DSAStack))
           return StmtError();
     }
   }
@@ -8964,9 +8975,9 @@
                                  buildPostUpdate(*this, ExprPostUpdates));
 }
 
-static bool
-FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
-                         Expr *NumIterations, Sema &SemaRef, Scope *S) {
+static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
+                                     Expr *NumIterations, Sema &SemaRef,
+                                     Scope *S, DSAStackTy *Stack) {
   // Walk the vars and build update/final expressions for the CodeGen.
   SmallVector<Expr *, 8> Updates;
   SmallVector<Expr *, 8> Finals;
@@ -8984,10 +8995,27 @@
   auto CurPrivate = Clause.privates().begin();
   auto LinKind = Clause.getModifier();
   for (auto &RefExpr : Clause.varlists()) {
+    SourceLocation ELoc;
+    SourceRange ERange;
+    Expr *SimpleRefExpr = RefExpr;
+    auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
+                              /*AllowArraySection=*/false);
+    ValueDecl *D = Res.first;
+    if (Res.second || !D) {
+      Updates.push_back(nullptr);
+      Finals.push_back(nullptr);
+      HasErrors = true;
+      continue;
+    }
+    if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) {
+      D = cast<MemberExpr>(CED->getInit()->IgnoreParenImpCasts())
+              ->getMemberDecl();
+    }
+    auto &&Info = Stack->isLoopControlVariable(D);
     Expr *InitExpr = *CurInit;
 
     // Build privatized reference to the current linear var.
-    auto DE = cast<DeclRefExpr>(RefExpr);
+    auto DE = cast<DeclRefExpr>(SimpleRefExpr);
     Expr *CapturedRef;
     if (LinKind == OMPC_LINEAR_uval)
       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
@@ -8998,18 +9026,27 @@
                            /*RefersToCapture=*/true);
 
     // Build update: Var = InitExpr + IV * Step
-    ExprResult Update =
-        BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
-                           InitExpr, IV, Step, /* Subtract */ false);
+    ExprResult Update;
+    if (!Info.first) {
+      Update =
+          BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
+                             InitExpr, IV, Step, /* Subtract */ false);
+    } else
+      Update = *CurPrivate;
     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
                                          /*DiscardedValue=*/true);
 
     // Build final: Var = InitExpr + NumIterations * Step
-    ExprResult Final =
-        BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
-                           InitExpr, NumIterations, Step, /* Subtract */ false);
+    ExprResult Final;
+    if (!Info.first) {
+      Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
+                                 InitExpr, NumIterations, Step,
+                                 /* Subtract */ false);
+    } else
+      Final = *CurPrivate;
     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
                                         /*DiscardedValue=*/true);
+
     if (!Update.isUsable() || !Final.isUsable()) {
       Updates.push_back(nullptr);
       Finals.push_back(nullptr);