]> granicus.if.org Git - clang/commitdiff
[analyzer] Use evalBind for C++ new of scalar types.
authorJordan Rose <jordan_rose@apple.com>
Wed, 27 Mar 2013 18:10:35 +0000 (18:10 +0000)
committerJordan Rose <jordan_rose@apple.com>
Wed, 27 Mar 2013 18:10:35 +0000 (18:10 +0000)
These types will not have a CXXConstructExpr to do the initialization for
them. Previously we just used a simple call to ProgramState::bindLoc, but
that doesn't trigger proper checker callbacks (like pointer escape).

Found by Anton Yartsev.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178160 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
test/Analysis/new.cpp

index d1a591c7fe06285939aa57efa31d6234e7733283..0fedf255d6f5a24993515a103650d01d6f627e4f 100644 (file)
@@ -331,20 +331,23 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
     State = State->BindExpr(CNE, LCtx, symVal);
   }
 
+  Bldr.generateNode(CNE, Pred, State);  
+
   // If the type is not a record, we won't have a CXXConstructExpr as an
   // initializer. Copy the value over.
   if (const Expr *Init = CNE->getInitializer()) {
     if (!isa<CXXConstructExpr>(Init)) {
-      QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
-      (void)ObjTy;
-      assert(!ObjTy->isRecordType());
+      assert(Bldr.getResults().size() == 1);
+      ExplodedNode *TmpN = *Bldr.getResults().begin();
+      Bldr.takeNodes(TmpN);
+
+      assert(!CNE->getType()->getPointeeCXXRecordDecl());
+
       SVal Location = State->getSVal(CNE, LCtx);
-      if (Optional<Loc> LV = Location.getAs<Loc>())
-        State = State->bindLoc(*LV, State->getSVal(Init, LCtx));
+      bool FirstInit = (Location == symVal);
+      evalBind(Dst, CNE, TmpN, Location, State->getSVal(Init, LCtx), FirstInit);
     }
   }
-
-  Bldr.generateNode(CNE, Pred, State);
 }
 
 void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 
index 701ac8bc55685960b329bd7346653f2be279e5f2..004a05ef94f66559f24ae876a09cb7fc795ab089 100644 (file)
@@ -76,7 +76,22 @@ struct PtrWrapper {
 
 PtrWrapper *testNewInvalidation() {
   // Ensure that we don't consider this a leak.
-  return new PtrWrapper(static_cast<int *>(malloc(4)));
+  return new PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
+}
+
+void testNewInvalidationPlacement(PtrWrapper *w) {
+  // Ensure that we don't consider this a leak.
+  new (w) PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
+}
+
+int **testNewInvalidationScalar() {
+  // Ensure that we don't consider this a leak.
+  return new (int *)(static_cast<int *>(malloc(4))); // no-warning
+}
+
+void testNewInvalidationScalarPlacement(int **p) {
+  // Ensure that we don't consider this a leak.
+  new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning
 }
 
 //--------------------------------------------------------------------