forked from OSchip/llvm-project
[analyzer] Use evalBind for C++ new of scalar types.
These types will not have a CXXConstructExpr to do the initialization for them. Previously we just used a simple call to ProgramState::bindLoc, but that doesn't trigger proper checker callbacks (like pointer escape). Found by Anton Yartsev. llvm-svn: 178160
This commit is contained in:
parent
b365d40415
commit
3503cb3572
|
@ -331,20 +331,23 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
|
||||||
State = State->BindExpr(CNE, LCtx, symVal);
|
State = State->BindExpr(CNE, LCtx, symVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bldr.generateNode(CNE, Pred, State);
|
||||||
|
|
||||||
// If the type is not a record, we won't have a CXXConstructExpr as an
|
// If the type is not a record, we won't have a CXXConstructExpr as an
|
||||||
// initializer. Copy the value over.
|
// initializer. Copy the value over.
|
||||||
if (const Expr *Init = CNE->getInitializer()) {
|
if (const Expr *Init = CNE->getInitializer()) {
|
||||||
if (!isa<CXXConstructExpr>(Init)) {
|
if (!isa<CXXConstructExpr>(Init)) {
|
||||||
QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
|
assert(Bldr.getResults().size() == 1);
|
||||||
(void)ObjTy;
|
ExplodedNode *TmpN = *Bldr.getResults().begin();
|
||||||
assert(!ObjTy->isRecordType());
|
Bldr.takeNodes(TmpN);
|
||||||
SVal Location = State->getSVal(CNE, LCtx);
|
|
||||||
if (Optional<Loc> LV = Location.getAs<Loc>())
|
|
||||||
State = State->bindLoc(*LV, State->getSVal(Init, LCtx));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bldr.generateNode(CNE, Pred, State);
|
assert(!CNE->getType()->getPointeeCXXRecordDecl());
|
||||||
|
|
||||||
|
SVal Location = State->getSVal(CNE, LCtx);
|
||||||
|
bool FirstInit = (Location == symVal);
|
||||||
|
evalBind(Dst, CNE, TmpN, Location, State->getSVal(Init, LCtx), FirstInit);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
|
void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
|
||||||
|
|
|
@ -76,7 +76,22 @@ struct PtrWrapper {
|
||||||
|
|
||||||
PtrWrapper *testNewInvalidation() {
|
PtrWrapper *testNewInvalidation() {
|
||||||
// Ensure that we don't consider this a leak.
|
// Ensure that we don't consider this a leak.
|
||||||
return new PtrWrapper(static_cast<int *>(malloc(4)));
|
return new PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNewInvalidationPlacement(PtrWrapper *w) {
|
||||||
|
// Ensure that we don't consider this a leak.
|
||||||
|
new (w) PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
|
||||||
|
}
|
||||||
|
|
||||||
|
int **testNewInvalidationScalar() {
|
||||||
|
// Ensure that we don't consider this a leak.
|
||||||
|
return new (int *)(static_cast<int *>(malloc(4))); // no-warning
|
||||||
|
}
|
||||||
|
|
||||||
|
void testNewInvalidationScalarPlacement(int **p) {
|
||||||
|
// Ensure that we don't consider this a leak.
|
||||||
|
new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue