forked from OSchip/llvm-project
[analyzer] Type information from C++ new expressions is perfect.
This improves our handling of dynamic_cast and devirtualization for objects allocated by 'new'. llvm-svn: 180051
This commit is contained in:
parent
7f3aa1081c
commit
3437669ca9
|
@ -27,7 +27,8 @@ namespace {
|
|||
class DynamicTypePropagation:
|
||||
public Checker< check::PreCall,
|
||||
check::PostCall,
|
||||
check::PostStmt<ImplicitCastExpr> > {
|
||||
check::PostStmt<ImplicitCastExpr>,
|
||||
check::PostStmt<CXXNewExpr> > {
|
||||
const ObjCObjectType *getObjectTypeForAllocAndNew(const ObjCMessageExpr *MsgE,
|
||||
CheckerContext &C) const;
|
||||
|
||||
|
@ -38,6 +39,7 @@ public:
|
|||
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
|
||||
void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
|
||||
void checkPostStmt(const ImplicitCastExpr *CastE, CheckerContext &C) const;
|
||||
void checkPostStmt(const CXXNewExpr *NewE, CheckerContext &C) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -190,6 +192,20 @@ void DynamicTypePropagation::checkPostStmt(const ImplicitCastExpr *CastE,
|
|||
return;
|
||||
}
|
||||
|
||||
void DynamicTypePropagation::checkPostStmt(const CXXNewExpr *NewE,
|
||||
CheckerContext &C) const {
|
||||
if (NewE->isArray())
|
||||
return;
|
||||
|
||||
// We only track dynamic type info for regions.
|
||||
const MemRegion *MR = C.getSVal(NewE).getAsRegion();
|
||||
if (!MR)
|
||||
return;
|
||||
|
||||
C.addTransition(C.getState()->setDynamicTypeInfo(MR, NewE->getType(),
|
||||
/*CanBeSubclass=*/false));
|
||||
}
|
||||
|
||||
const ObjCObjectType *
|
||||
DynamicTypePropagation::getObjectTypeForAllocAndNew(const ObjCMessageExpr *MsgE,
|
||||
CheckerContext &C) const {
|
||||
|
|
|
@ -351,9 +351,7 @@ namespace VirtualWithSisterCasts {
|
|||
|
||||
void testCastViaNew(B *b) {
|
||||
Grandchild *g = new (b) Grandchild();
|
||||
// FIXME: We actually now have perfect type info because of 'new'.
|
||||
// This should be TRUE.
|
||||
clang_analyzer_eval(g->foo() == 42); // expected-warning{{UNKNOWN}}
|
||||
clang_analyzer_eval(g->foo() == 42); // expected-warning{{TRUE}}
|
||||
|
||||
g->x = 42;
|
||||
clang_analyzer_eval(g->x == 42); // expected-warning{{TRUE}}
|
||||
|
|
|
@ -16,6 +16,11 @@ void testKnown() {
|
|||
clang_analyzer_eval(a.get() == 0); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
void testNew() {
|
||||
A *a = new A();
|
||||
clang_analyzer_eval(a->get() == 0); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
|
||||
namespace ReinterpretDisruptsDynamicTypeInfo {
|
||||
class Parent {};
|
||||
|
|
Loading…
Reference in New Issue