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@-2{{Potential leak of memory pointed to by 'c3'}}
+// expected-warning@-4{{Potential memory leak}}
 #endif
 
 void testOpNewArray() {
@@ -39,6 +40,7 @@
 }
 #ifdef LEAKS
 // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+// expected-warning@-4{{Potential memory leak}}
 #endif
 
 
@@ -52,6 +54,7 @@
 }
 #ifdef LEAKS
 // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+// expected-warning@-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);
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@-2{{Potential leak of memory pointed to by 'c3'}}
+// expected-warning@-4{{Potential memory leak}}
 #endif
 
 void testOpNewArray() {
@@ -39,6 +40,7 @@
 }
 #ifdef LEAKS
 // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+// expected-warning@-4{{Potential memory leak}}
 #endif
 
 
@@ -52,6 +54,7 @@
 }
 #ifdef LEAKS
 // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
+// expected-warning@-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);
 
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to