[PATCH] Model Constructor corresponding to a new call

Karthik Bhat kv.bhat at samsung.com
Tue Jan 28 05:06:44 PST 2014


  Hi Jordan,
  I suppose you wanted me to inline the allocator call during a call to new first. This patch inlines the allocator call but i'm still facing few problems.
  If i code as -
    void* operator new(size_t num)
    {
      return 0;
    }

    int main() {
      int* i = new int(1);
      *i = 1;
      delete i;
      return 0;
    }
  In the above code we are not able to detect the null deref at   *i = 1; . I suppose that is because we are conjuring a new symbol in VisitCXXNewExpr which is being used as output of new expression. My doubt was how do i make sure that the VisitCXXNewExpr uses the output of VisitCXXNewAllocatorCall?
  I tried something like -
   1) conjure a symbol in VisitCXXNewAllocatorCall.
   2) Bind it to conjured symbol to CXXNewExpr
   3) Call getSVal in VisitCXXNewExpr with the CXXNewExpr and location context to get back the conjured symbol.
  but unfortunetly in VisitCXXNewExpr when i call getSVal with CXXNewExpr and LocationContext i get the result as Unknown instead of the symbol conjured in VisitCXXNewAllocatorCall.
  How do i make sure that VisitCXXNewExpr uses the result of VisitCXXNewAllocatorCall? It would be great if you could guide me here.

  Thanks
  Karthik Bhat

Hi jordan_rose,

http://llvm-reviews.chandlerc.com/D2616

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D2616?vs=6639&id=6709#toc

Files:
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  test/Analysis/NewDelete-custom.cpp
  test/Analysis/inline.cpp
  include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h

Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -553,12 +553,8 @@
 
 void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE,
                                      ExplodedNode *Pred) {
-  //TODO: Implement VisitCXXNewAllocatorCall
   ExplodedNodeSet Dst;
-  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
-  const LocationContext *LCtx = Pred->getLocationContext();
-  PostImplicitCall PP(NE->getOperatorNew(), NE->getLocStart(), LCtx);
-  Bldr.generateNode(PP, Pred->getState(), Pred);
+  VisitCXXNewAllocatorCall(NE, Pred, Dst);
   Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
 }
 
Index: lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -664,9 +664,7 @@
     break;
   }
   case CE_CXXAllocator:
-    // Do not inline allocators until we model deallocators.
-    // This is unfortunate, but basically necessary for smart pointers and such.
-    return CIP_DisallowedAlways;
+    break;
   case CE_ObjCMessage:
     if (!Opts.mayInlineObjCMethod())
       return CIP_DisallowedAlways;
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -329,6 +329,32 @@
                                              *Call, *this);
 }
 
+void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
+                                          ExplodedNode *Pred,
+                                          ExplodedNodeSet &Dst) {
+  ProgramStateRef State = Pred->getState();
+  const LocationContext *LCtx = Pred->getLocationContext();
+  CallEventManager &CEMgr = getStateManager().getCallEventManager();
+  CallEventRef<CXXAllocatorCall> Call =
+    CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                Call->getSourceRange().getBegin(),
+                                "Error evaluating New Allocator Call");
+
+  ExplodedNodeSet DstPreCall;
+  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
+                                            *Call, *this);
+
+  ExplodedNodeSet DstInvalidated;
+  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
+  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
+       I != E; ++I)
+    defaultEvalCall(Bldr, *I, *Call);
+  getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
+                                             *Call, *this);
+}
+
+
 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
                                    ExplodedNodeSet &Dst) {
   // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
Index: test/Analysis/NewDelete-custom.cpp
===================================================================
--- test/Analysis/NewDelete-custom.cpp
+++ test/Analysis/NewDelete-custom.cpp
@@ -28,6 +28,7 @@
 }
 #ifdef LEAKS
 // expected-warning at -2{{Potential leak of memory pointed to by 'c3'}}
+// expected-warning at -4{{Potential memory leak}}
 #endif
 
 void testOpNewArray() {
@@ -39,6 +40,7 @@
 }
 #ifdef LEAKS
 // expected-warning at -2{{Potential leak of memory pointed to by 'p'}}
+// expected-warning at -4{{Potential memory leak}}
 #endif
 
 
@@ -52,6 +54,7 @@
 }
 #ifdef LEAKS
 // expected-warning at -2{{Potential leak of memory pointed to by 'p'}}
+// expected-warning at -4{{Potential memory leak}}
 #endif
 
 
Index: test/Analysis/inline.cpp
===================================================================
--- test/Analysis/inline.cpp
+++ test/Analysis/inline.cpp
@@ -9,6 +9,7 @@
 // This is the standard placement new.
 inline void* operator new(size_t, void* __p) throw()
 {
+  clang_analyzer_checkInlined(true);// expected-warning{{TRUE}}
   return __p;
 }
 
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -421,6 +421,10 @@
                           const Stmt *S, bool IsBaseDtor,
                           ExplodedNode *Pred, ExplodedNodeSet &Dst);
 
+  void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
+                                ExplodedNode *Pred,
+                                ExplodedNodeSet &Dst);
+
   void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
                        ExplodedNodeSet &Dst);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2616.2.patch
Type: text/x-patch
Size: 4819 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140128/91ae8566/attachment.bin>


More information about the cfe-commits mailing list