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/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 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: 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: 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; }