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;
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;
};
}
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 {
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}}