r322780 - [analyzer] operator new: Fix memory space for the returned region.
Artem Dergachev via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 17 14:58:35 PST 2018
Author: dergachev
Date: Wed Jan 17 14:58:35 2018
New Revision: 322780
URL: http://llvm.org/viewvc/llvm-project?rev=322780&view=rev
Log:
[analyzer] operator new: Fix memory space for the returned region.
Make sure that with c++-allocator-inlining=true we have the return value of
conservatively evaluated operator new() in the correct memory space (heap).
This is a regression/omission that worked well in c++-allocator-inlining=false.
Heap regions are superior to regular symbolic regions because they have
stricter aliasing constraints: heap regions do not alias each other or global
variables.
Differential Revision: https://reviews.llvm.org/D41266
rdar://problem/12180598
Added:
cfe/trunk/test/Analysis/new-ctor-null.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/trunk/test/Analysis/NewDelete-checker-test.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=322780&r1=322779&r2=322780&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Wed Jan 17 14:58:35 2018
@@ -479,8 +479,10 @@ void ExprEngine::VisitCXXNewAllocatorCal
ExplodedNodeSet DstPostCall;
StmtNodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx);
- for (auto I : DstPreCall)
+ for (auto I : DstPreCall) {
+ // FIXME: Provide evalCall for checkers?
defaultEvalCall(CallBldr, I, *Call);
+ }
// If the call is inlined, DstPostCall will be empty and we bail out now.
// Store return value of operator new() for future use, until the actual
@@ -507,7 +509,6 @@ void ExprEngine::VisitCXXNewAllocatorCal
*Call, *this);
}
-
void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
ExplodedNodeSet &Dst) {
// FIXME: Much of this should eventually migrate to CXXAllocatorCall.
@@ -520,18 +521,8 @@ void ExprEngine::VisitCXXNewExpr(const C
SVal 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);
- }
+ bool IsStandardGlobalOpNewFunction =
+ FD->isReplaceableGlobalAllocationFunction();
ProgramStateRef State = Pred->getState();
@@ -587,9 +578,8 @@ void ExprEngine::VisitCXXNewExpr(const C
if (CNE->isArray()) {
// FIXME: allocating an array requires simulating the constructors.
// For now, just return a symbolicated region.
- if (!AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
- const SubRegion *NewReg =
- symVal.castAs<loc::MemRegionVal>().getRegionAs<SubRegion>();
+ if (const SubRegion *NewReg =
+ dyn_cast_or_null<SubRegion>(symVal.getAsRegion())) {
QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
const ElementRegion *EleReg =
getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=322780&r1=322779&r2=322780&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Wed Jan 17 14:58:35 2018
@@ -573,7 +573,19 @@ ProgramStateRef ExprEngine::bindReturnVa
QualType ResultTy = Call.getResultType();
SValBuilder &SVB = getSValBuilder();
unsigned Count = currBldrCtx->blockCount();
- SVal R = SVB.conjureSymbolVal(nullptr, E, LCtx, ResultTy, Count);
+
+ // See if we need to conjure a heap pointer instead of
+ // a regular unknown pointer.
+ bool IsHeapPointer = false;
+ if (const auto *CNE = dyn_cast<CXXNewExpr>(E))
+ if (CNE->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
+ // FIXME: Delegate this to evalCall in MallocChecker?
+ IsHeapPointer = true;
+ }
+
+ SVal R = IsHeapPointer
+ ? SVB.getConjuredHeapSymbolVal(E, LCtx, Count)
+ : SVB.conjureSymbolVal(nullptr, E, LCtx, ResultTy, Count);
return State->BindExpr(E, LCtx, R);
}
Modified: cfe/trunk/test/Analysis/NewDelete-checker-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NewDelete-checker-test.cpp?rev=322780&r1=322779&r2=322780&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/NewDelete-checker-test.cpp (original)
+++ cfe/trunk/test/Analysis/NewDelete-checker-test.cpp Wed Jan 17 14:58:35 2018
@@ -1,5 +1,7 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -analyzer-config c++-allocator-inlining=true -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -analyzer-config c++-allocator-inlining=true -verify %s
#include "Inputs/system-header-simulator-cxx.h"
typedef __typeof__(sizeof(int)) size_t;
Added: cfe/trunk/test/Analysis/new-ctor-null.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/new-ctor-null.cpp?rev=322780&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/new-ctor-null.cpp (added)
+++ cfe/trunk/test/Analysis/new-ctor-null.cpp Wed Jan 17 14:58:35 2018
@@ -0,0 +1,23 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-allocator-inlining=true -std=c++11 -verify %s
+
+void clang_analyzer_eval(bool);
+
+typedef __typeof__(sizeof(int)) size_t;
+
+void *operator new(size_t size) throw() {
+ return nullptr;
+}
+void *operator new[](size_t size) throw() {
+ return nullptr;
+}
+
+struct S {
+ int x;
+ S() : x(1) {}
+ ~S() {}
+};
+
+void testArrays() {
+ S *s = new S[10]; // no-crash
+ s[0].x = 2; // expected-warning{{Dereference of null pointer}}
+}
More information about the cfe-commits
mailing list