Teach static analyzer about the basics of handling new[].  We still don't simulate constructors, but at least the analyzer doesn't think the return value is uninitialized.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128611 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/CXXExprEngine.cpp b/lib/StaticAnalyzer/Core/CXXExprEngine.cpp
index b015d4f..b299fcc 100644
--- a/lib/StaticAnalyzer/Core/CXXExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CXXExprEngine.cpp
@@ -199,20 +199,23 @@
 
 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
                                    ExplodedNodeSet &Dst) {
-  if (CNE->isArray()) {
-    // FIXME: allocating an array has not been handled.
-    return;
-  }
-
+  
   unsigned Count = Builder->getCurrentBlockCount();
   DefinedOrUnknownSVal symVal =
     svalBuilder.getConjuredSymbolVal(NULL, CNE, CNE->getType(), Count);
-  const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();
-
+  const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();  
   QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
-
   const ElementRegion *EleReg = 
-                         getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
+    getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
+
+  if (CNE->isArray()) {
+    // FIXME: allocating an array requires simulating the constructors.
+    // For now, just return a symbolicated region.
+    const GRState *state = GetState(Pred);
+    state = state->BindExpr(CNE, loc::MemRegionVal(EleReg));
+    MakeNode(Dst, CNE, Pred, state);
+    return;
+  }
 
   // Evaluate constructor arguments.
   const FunctionProtoType *FnType = NULL;
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index 3b8d4e3..26a3152 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -255,4 +255,12 @@
   return false;
 }
 
+// Test handling of new[].
+void rdar9212512() {
+  int *x = new int[10];
+  for (unsigned i = 0 ; i < 2 ; ++i) {
+    // This previously triggered an uninitialized values warning.
+    x[i] = 1;  // no-warning
+  }
+}