r201122 - [analyzer] Inline C++ operator new when c++-inline-allocators is turned on.
Jordan Rose
jordan_rose at apple.com
Mon Feb 10 18:21:06 PST 2014
Author: jrose
Date: Mon Feb 10 20:21:06 2014
New Revision: 201122
URL: http://llvm.org/viewvc/llvm-project?rev=201122&view=rev
Log:
[analyzer] Inline C++ operator new when c++-inline-allocators is turned on.
This will let us stage in the modeling of operator new. The -analyzer-config
opton 'c++-inline-allocators' is currently off by default.
Patch by Karthik Bhat!
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/trunk/test/Analysis/inline.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=201122&r1=201121&r2=201122&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Mon Feb 10 20:21:06 2014
@@ -199,6 +199,9 @@ private:
/// \sa mayInlineTemplateFunctions
Optional<bool> InlineTemplateFunctions;
+ /// \sa mayInlineCXXAllocator
+ Optional<bool> InlineCXXAllocator;
+
/// \sa mayInlineCXXContainerCtorsAndDtors
Optional<bool> InlineCXXContainerCtorsAndDtors;
@@ -291,6 +294,12 @@ public:
/// accepts the values "true" and "false".
bool mayInlineTemplateFunctions();
+ /// Returns whether or not allocator call may be considered for inlining.
+ ///
+ /// This is controlled by the 'c++-allocator-inlining' config option, which
+ /// accepts the values "true" and "false".
+ bool mayInlineCXXAllocator();
+
/// Returns whether or not constructors and destructors of C++ container
/// objects may be considered for inlining.
///
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=201122&r1=201121&r2=201122&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Mon Feb 10 20:21:06 2014
@@ -421,6 +421,10 @@ public:
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);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=201122&r1=201121&r2=201122&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Mon Feb 10 20:21:06 2014
@@ -134,6 +134,12 @@ bool AnalyzerOptions::mayInlineTemplateF
/*Default=*/true);
}
+bool AnalyzerOptions::mayInlineCXXAllocator() {
+ return getBooleanOption(InlineCXXAllocator,
+ "c++-allocator-inlining",
+ /*Default=*/false);
+}
+
bool AnalyzerOptions::mayInlineCXXContainerCtorsAndDtors() {
return getBooleanOption(InlineCXXContainerCtorsAndDtors,
"c++-container-inlining",
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=201122&r1=201121&r2=201122&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Mon Feb 10 20:21:06 2014
@@ -532,6 +532,11 @@ void CoreEngine::enqueueStmtNode(Explode
return;
}
+ if ((*Block)[Idx].getKind() == CFGElement::NewAllocator) {
+ WList->enqueue(N, Block, Idx+1);
+ return;
+ }
+
// At this point, we know we're processing a normal statement.
CFGStmt CS = (*Block)[Idx].castAs<CFGStmt>();
PostStmt Loc(CS.getStmt(), N->getLocationContext());
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=201122&r1=201121&r2=201122&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Feb 10 20:21:06 2014
@@ -553,12 +553,20 @@ void ExprEngine::ProcessImplicitDtor(con
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);
+ AnalysisManager &AMgr = getAnalysisManager();
+ AnalyzerOptions &Opts = AMgr.options;
+ // TODO: We're not evaluating allocators for all cases just yet as
+ // we're not handling the return value correctly, which causes false
+ // positives when the alpha.cplusplus.NewDeleteLeaks check is on.
+ if (Opts.mayInlineCXXAllocator())
+ VisitCXXNewAllocatorCall(NE, Pred, Dst);
+ else {
+ NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+ const LocationContext *LCtx = Pred->getLocationContext();
+ PostImplicitCall PP(NE->getOperatorNew(), NE->getLocStart(), LCtx);
+ Bldr.generateNode(PP, Pred->getState(), Pred);
+ }
Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=201122&r1=201121&r2=201122&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Mon Feb 10 20:21:06 2014
@@ -329,6 +329,32 @@ void ExprEngine::VisitCXXDestructor(Qual
*Call, *this);
}
+void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
+ ExplodedNode *Pred,
+ ExplodedNodeSet &Dst) {
+ ProgramStateRef State = Pred->getState();
+ const LocationContext *LCtx = Pred->getLocationContext();
+ PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+ CNE->getStartLoc(),
+ "Error evaluating New Allocator Call");
+ CallEventManager &CEMgr = getStateManager().getCallEventManager();
+ CallEventRef<CXXAllocatorCall> Call =
+ CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
+
+ 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.
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=201122&r1=201121&r2=201122&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Mon Feb 10 20:21:06 2014
@@ -664,6 +664,8 @@ static CallInlinePolicy mayInlineCallKin
break;
}
case CE_CXXAllocator:
+ if (Opts.mayInlineCXXAllocator())
+ break;
// Do not inline allocators until we model deallocators.
// This is unfortunate, but basically necessary for smart pointers and such.
return CIP_DisallowedAlways;
Modified: cfe/trunk/test/Analysis/inline.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.cpp?rev=201122&r1=201121&r2=201122&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline.cpp (original)
+++ cfe/trunk/test/Analysis/inline.cpp Mon Feb 10 20:21:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -analyzer-config c++-allocator-inlining=true -verify %s
void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);
@@ -9,6 +9,7 @@ extern "C" void *malloc(size_t);
// This is the standard placement new.
inline void* operator new(size_t, void* __p) throw()
{
+ clang_analyzer_checkInlined(true);// expected-warning{{TRUE}}
return __p;
}
More information about the cfe-commits
mailing list