diff options
author | Anton Yartsev <anton.yartsev@gmail.com> | 2013-03-28 16:10:38 +0000 |
---|---|---|
committer | Anton Yartsev <anton.yartsev@gmail.com> | 2013-03-28 16:10:38 +0000 |
commit | 697462881c4b9b704c7859f4bab0a6116c684bb1 (patch) | |
tree | b80287ad1d017e8c8773445845370d61457ded97 /lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | |
parent | 829d187e2100d2cfd85acefc2e867d12336e393f (diff) |
[analyzer] For now assume all standard global 'operator new' functions allocate memory in heap.
+ Improved test coverage for cplusplus.NewDelete checker.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178244 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngineCXX.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 0fedf255d6..c1dd6b2220 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -278,11 +278,32 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, unsigned blockCount = currBldrCtx->blockCount(); const LocationContext *LCtx = Pred->getLocationContext(); - DefinedOrUnknownSVal symVal = svalBuilder.conjureSymbolVal(0, CNE, LCtx, - CNE->getType(), - blockCount); - ProgramStateRef State = Pred->getState(); + DefinedOrUnknownSVal symVal = UnknownVal(); + FunctionDecl *FD = CNE->getOperatorNew(); + + bool IsStandardGlobalOpNewFunction = false; + if (FD && !isa<CXXMethodDecl>(FD) && !FD->isVariadic()) { + if (FD->getNumParams() == 2) { + QualType T = FD->getParamDecl(1)->getType(); + if (const IdentifierInfo *II = T.getBaseTypeIdentifier()) + // NoThrow placement new behaves as a standard new. + IsStandardGlobalOpNewFunction = II->getName().equals("nothrow_t"); + } + else + // Placement forms are considered non-standard. + IsStandardGlobalOpNewFunction = (FD->getNumParams() == 1); + } + + // We assume all standard global 'operator new' functions allocate memory in + // heap. We realize this is an approximation that might not correctly model + // a custom global allocator. + if (IsStandardGlobalOpNewFunction) + symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount); + else + symVal = svalBuilder.conjureSymbolVal(0, CNE, LCtx, CNE->getType(), + blockCount); + ProgramStateRef State = Pred->getState(); CallEventManager &CEMgr = getStateManager().getCallEventManager(); CallEventRef<CXXAllocatorCall> Call = CEMgr.getCXXAllocatorCall(CNE, State, LCtx); @@ -296,7 +317,6 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, // is not declared as non-throwing, failures /must/ be signalled by // exceptions, and thus the return value will never be NULL. // C++11 [basic.stc.dynamic.allocation]p3. - FunctionDecl *FD = CNE->getOperatorNew(); if (FD && getContext().getLangOpts().CXXExceptions) { QualType Ty = FD->getType(); if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>()) |