Remove custom handling of array copies in lambda by-value array capture and
copy constructors of classes with array members, instead using
ArrayInitLoopExpr to represent the initialization loop.

This exposed a bug in the static analyzer where it was unable to differentiate
between zero-initialized and unknown array values, which has also been fixed
here.

llvm-svn: 289618
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 709c4af..05d0567 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -562,140 +562,6 @@
                                           isBaseVirtual);
 }
 
-/// Initialize a member of aggregate type using the given expression
-/// as an initializer.
-///
-/// The member may be an array.  If so:
-/// - the destination l-value will be a pointer of the *base* element type,
-/// - ArrayIndexVar will be a pointer to a variable containing the current
-///   index within the destination array, and
-/// - ArrayIndexes will be an array of index variables, one for each level
-///   of array nesting, which will need to be updated as appropriate for the
-///   array structure.
-///
-/// On an array, this function will invoke itself recursively.  Each time,
-/// it drills into one nesting level of the member type and sets up a
-/// loop updating the appropriate array index variable.
-static void EmitAggMemberInitializer(CodeGenFunction &CGF,
-                                     LValue LHS,
-                                     Expr *Init,
-                                     Address ArrayIndexVar,
-                                     QualType T,
-                                     ArrayRef<VarDecl *> ArrayIndexes,
-                                     unsigned Index) {
-  assert(ArrayIndexVar.isValid() == (ArrayIndexes.size() != 0));
-
-  if (Index == ArrayIndexes.size()) {
-    LValue LV = LHS;
-
-    Optional<CodeGenFunction::RunCleanupsScope> Scope;
-
-    if (ArrayIndexVar.isValid()) {
-      // When we're processing an array, the temporaries from each
-      // element's construction are destroyed immediately.
-      Scope.emplace(CGF);
-
-      // If we have an array index variable, load it and use it as an offset.
-      // Then, increment the value.
-      llvm::Value *Dest = LHS.getPointer();
-      llvm::Value *ArrayIndex = CGF.Builder.CreateLoad(ArrayIndexVar);
-      Dest = CGF.Builder.CreateInBoundsGEP(Dest, ArrayIndex, "destaddress");
-      llvm::Value *Next = llvm::ConstantInt::get(ArrayIndex->getType(), 1);
-      Next = CGF.Builder.CreateAdd(ArrayIndex, Next, "inc");
-      CGF.Builder.CreateStore(Next, ArrayIndexVar);
-
-      // Update the LValue.
-      CharUnits EltSize = CGF.getContext().getTypeSizeInChars(T);
-      CharUnits Align = LV.getAlignment().alignmentOfArrayElement(EltSize);
-      LV.setAddress(Address(Dest, Align));
-
-      // Enter a partial-array EH cleanup to destroy previous members
-      // of the array if this initialization throws.
-      if (CGF.CGM.getLangOpts().Exceptions) {
-        if (auto DtorKind = T.isDestructedType()) {
-          if (CGF.needsEHCleanup(DtorKind)) {
-            CGF.pushRegularPartialArrayCleanup(LHS.getPointer(),
-                                               LV.getPointer(), T,
-                                               LV.getAlignment(),
-                                               CGF.getDestroyer(DtorKind));
-          }
-        }
-      }
-    }
-
-    switch (CGF.getEvaluationKind(T)) {
-    case TEK_Scalar:
-      CGF.EmitScalarInit(Init, /*decl*/ nullptr, LV, false);
-      break;
-    case TEK_Complex:
-      CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true);
-      break;
-    case TEK_Aggregate: {
-      AggValueSlot Slot =
-        AggValueSlot::forLValue(LV,
-                                AggValueSlot::IsDestructed,
-                                AggValueSlot::DoesNotNeedGCBarriers,
-                                AggValueSlot::IsNotAliased);
-
-      CGF.EmitAggExpr(Init, Slot);
-      break;
-    }
-    }
-
-    return;
-  }
-
-  const ConstantArrayType *Array = CGF.getContext().getAsConstantArrayType(T);
-  assert(Array && "Array initialization without the array type?");
-  Address IndexVar = CGF.GetAddrOfLocalVar(ArrayIndexes[Index]);
-
-  // Initialize this index variable to zero.
-  llvm::Value* Zero
-    = llvm::Constant::getNullValue(IndexVar.getElementType());
-  CGF.Builder.CreateStore(Zero, IndexVar);
-
-  // Start the loop with a block that tests the condition.
-  llvm::BasicBlock *CondBlock = CGF.createBasicBlock("for.cond");
-  llvm::BasicBlock *AfterFor = CGF.createBasicBlock("for.end");
-
-  CGF.EmitBlock(CondBlock);
-
-  llvm::BasicBlock *ForBody = CGF.createBasicBlock("for.body");
-  // Generate: if (loop-index < number-of-elements) fall to the loop body,
-  // otherwise, go to the block after the for-loop.
-  uint64_t NumElements = Array->getSize().getZExtValue();
-  llvm::Value *Counter = CGF.Builder.CreateLoad(IndexVar);
-  llvm::Value *NumElementsPtr =
-    llvm::ConstantInt::get(Counter->getType(), NumElements);
-  llvm::Value *IsLess = CGF.Builder.CreateICmpULT(Counter, NumElementsPtr,
-                                                  "isless");
-
-  // If the condition is true, execute the body.
-  CGF.Builder.CreateCondBr(IsLess, ForBody, AfterFor);
-
-  CGF.EmitBlock(ForBody);
-  llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc");
-
-  // Inside the loop body recurse to emit the inner loop or, eventually, the
-  // constructor call.
-  EmitAggMemberInitializer(CGF, LHS, Init, ArrayIndexVar,
-                           Array->getElementType(), ArrayIndexes, Index + 1);
-
-  CGF.EmitBlock(ContinueBlock);
-
-  // Emit the increment of the loop counter.
-  llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
-  Counter = CGF.Builder.CreateLoad(IndexVar);
-  NextVal = CGF.Builder.CreateAdd(Counter, NextVal, "inc");
-  CGF.Builder.CreateStore(NextVal, IndexVar);
-
-  // Finally, branch back up to the condition for the next iteration.
-  CGF.EmitBranch(CondBlock);
-
-  // Emit the fall-through block.
-  CGF.EmitBlock(AfterFor, true);
-}
-
 static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D) {
   auto *CD = dyn_cast<CXXConstructorDecl>(D);
   if (!(CD && CD->isCopyOrMoveConstructor()) &&
@@ -779,14 +645,11 @@
     }
   }
 
-  ArrayRef<VarDecl *> ArrayIndexes;
-  if (MemberInit->getNumArrayIndices())
-    ArrayIndexes = MemberInit->getArrayIndices();
-  CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit(), ArrayIndexes);
+  CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit());
 }
 
 void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS,
-                                Expr *Init, ArrayRef<VarDecl *> ArrayIndexes) {
+                                              Expr *Init) {
   QualType FieldType = Field->getType();
   switch (getEvaluationKind(FieldType)) {
   case TEK_Scalar:
@@ -801,30 +664,13 @@
     EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true);
     break;
   case TEK_Aggregate: {
-    Address ArrayIndexVar = Address::invalid();
-    if (ArrayIndexes.size()) {
-      // The LHS is a pointer to the first object we'll be constructing, as
-      // a flat array.
-      QualType BaseElementTy = getContext().getBaseElementType(FieldType);
-      llvm::Type *BasePtr = ConvertType(BaseElementTy);
-      BasePtr = llvm::PointerType::getUnqual(BasePtr);
-      Address BaseAddrPtr = Builder.CreateBitCast(LHS.getAddress(), BasePtr);
-      LHS = MakeAddrLValue(BaseAddrPtr, BaseElementTy);
-
-      // Create an array index that will be used to walk over all of the
-      // objects we're constructing.
-      ArrayIndexVar = CreateMemTemp(getContext().getSizeType(), "object.index");
-      llvm::Value *Zero =
-        llvm::Constant::getNullValue(ArrayIndexVar.getElementType());
-      Builder.CreateStore(Zero, ArrayIndexVar);
-
-      // Emit the block variables for the array indices, if any.
-      for (unsigned I = 0, N = ArrayIndexes.size(); I != N; ++I)
-        EmitAutoVarDecl(*ArrayIndexes[I]);
-    }
-
-    EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType,
-                             ArrayIndexes, 0);
+    AggValueSlot Slot =
+      AggValueSlot::forLValue(LHS,
+                              AggValueSlot::IsDestructed,
+                              AggValueSlot::DoesNotNeedGCBarriers,
+                              AggValueSlot::IsNotAliased);
+    EmitAggExpr(Init, Slot);
+    break;
   }
   }
 
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index d756eca..9ead6b8 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -1328,27 +1328,12 @@
   llvm::Value *begin = Builder.CreateInBoundsGEP(destPtr.getPointer(), indices,
                                                  "arrayinit.begin");
 
-  QualType elementType = E->getSubExpr()->getType();
+  QualType elementType =
+      CGF.getContext().getAsArrayType(E->getType())->getElementType();
   CharUnits elementSize = CGF.getContext().getTypeSizeInChars(elementType);
   CharUnits elementAlign =
       destPtr.getAlignment().alignmentOfArrayElement(elementSize);
 
-  // Prepare for a cleanup.
-  QualType::DestructionKind dtorKind = elementType.isDestructedType();
-  Address endOfInit = Address::invalid();
-  EHScopeStack::stable_iterator cleanup;
-  llvm::Instruction *cleanupDominator = nullptr;
-  if (CGF.needsEHCleanup(dtorKind)) {
-    endOfInit = CGF.CreateTempAlloca(begin->getType(), CGF.getPointerAlign(),
-                                     "arrayinit.endOfInit");
-    CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType,
-                                         elementAlign,
-                                         CGF.getDestroyer(dtorKind));
-    cleanup = CGF.EHStack.stable_begin();
-  } else {
-    dtorKind = QualType::DK_none;
-  }
-
   llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
   llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");
 
@@ -1359,11 +1344,22 @@
   index->addIncoming(zero, entryBB);
   llvm::Value *element = Builder.CreateInBoundsGEP(begin, index);
 
-  // Tell the EH cleanup that we finished with the last element.
-  if (endOfInit.isValid()) Builder.CreateStore(element, endOfInit);
+  // Prepare for a cleanup.
+  QualType::DestructionKind dtorKind = elementType.isDestructedType();
+  EHScopeStack::stable_iterator cleanup;
+  if (CGF.needsEHCleanup(dtorKind)) {
+    CGF.pushRegularPartialArrayCleanup(
+        begin, element, elementType, elementAlign, CGF.getDestroyer(dtorKind));
+    cleanup = CGF.EHStack.stable_begin();
+  } else {
+    dtorKind = QualType::DK_none;
+  }
 
   // Emit the actual filler expression.
   {
+    // Temporaries created in an array initialization loop are destroyed
+    // at the end of each iteration.
+    CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);
     CodeGenFunction::ArrayInitLoopExprScope Scope(CGF, index);
     LValue elementLV =
         CGF.MakeAddrLValue(Address(element, elementAlign), elementType);
@@ -1385,7 +1381,8 @@
   CGF.EmitBlock(endBB);
 
   // Leave the partial-array cleanup if we entered one.
-  if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator);
+  if (dtorKind)
+    CGF.DeactivateCleanupBlock(cleanup, index);
 }
 
 void AggExprEmitter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index ab2468e..71c8fb8 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -2140,10 +2140,7 @@
       auto VAT = CurField->getCapturedVLAType();
       EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
     } else {
-      ArrayRef<VarDecl *> ArrayIndexes;
-      if (CurField->getType()->isArrayType())
-        ArrayIndexes = E->getCaptureInitIndexVars(i);
-      EmitInitializerForField(*CurField, LV, *i, ArrayIndexes);
+      EmitInitializerForField(*CurField, LV, *i);
     }
   }
 }
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index ba0064f..e4b1581 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2206,7 +2206,7 @@
       auto VAT = CurField->getCapturedVLAType();
       EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
     } else {
-      EmitInitializerForField(*CurField, LV, *I, None);
+      EmitInitializerForField(*CurField, LV, *I);
     }
   }
 
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index eddaf65..bc4efd3 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1601,8 +1601,7 @@
   void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type,
                         FunctionArgList &Args);
 
-  void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init,
-                               ArrayRef<VarDecl *> ArrayIndexes);
+  void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init);
 
   /// Struct with all informations about dynamic [sub]class needed to set vptr.
   struct VPtr {