diff options
| author | Jordan Rose <jordan_rose@apple.com> | 2013-04-22 21:36:44 +0000 |
|---|---|---|
| committer | Jordan Rose <jordan_rose@apple.com> | 2013-04-22 21:36:44 +0000 |
| commit | 3437669ca94236918c654f042e33dfa0c32cbd0f (patch) | |
| tree | 51b4ffeacba98e3e1e790fcec55ec5fa7998d81b | |
| parent | 7f3aa1081cf0bafb0d420932d4d60b122df405f7 (diff) | |
| download | bcm5719-llvm-3437669ca94236918c654f042e33dfa0c32cbd0f.tar.gz bcm5719-llvm-3437669ca94236918c654f042e33dfa0c32cbd0f.zip | |
[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
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp | 18 | ||||
| -rw-r--r-- | clang/test/Analysis/inline.cpp | 4 | ||||
| -rw-r--r-- | clang/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp | 5 |
3 files changed, 23 insertions, 4 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp index 9f176a4b5bf..759aa6605ee 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp @@ -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 { diff --git a/clang/test/Analysis/inline.cpp b/clang/test/Analysis/inline.cpp index a16fa00d12b..62bce284721 100644 --- a/clang/test/Analysis/inline.cpp +++ b/clang/test/Analysis/inline.cpp @@ -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}} diff --git a/clang/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp b/clang/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp index 890e5640cef..d219446fc96 100644 --- a/clang/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp +++ b/clang/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp @@ -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 {}; |

