diff options
| author | Anna Zaks <ganna@apple.com> | 2012-09-05 23:41:54 +0000 |
|---|---|---|
| committer | Anna Zaks <ganna@apple.com> | 2012-09-05 23:41:54 +0000 |
| commit | 3245e584db566ac81c87dfc4b87003bf8a7c2405 (patch) | |
| tree | c705465af39365e0b4bb1528d2331b6dcaf7bd7a /clang | |
| parent | b4dbc17acd0b854f4071b876f4f36d33a630bb28 (diff) | |
| download | bcm5719-llvm-3245e584db566ac81c87dfc4b87003bf8a7c2405.tar.gz bcm5719-llvm-3245e584db566ac81c87dfc4b87003bf8a7c2405.zip | |
[analyzer] Enhance the member expr tracking to account for references.
As per Jordan's suggestion. (Came out of code review for r163261.)
llvm-svn: 163269
Diffstat (limited to 'clang')
4 files changed, 27 insertions, 2 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h index f3206964e3a..fe64f93d0d3 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h @@ -256,6 +256,8 @@ void trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R); const Stmt *GetDerefExpr(const ExplodedNode *N); const Stmt *GetDenomExpr(const ExplodedNode *N); const Stmt *GetRetValExpr(const ExplodedNode *N); +bool isDeclRefExprToReference(const Expr *E); + } // end namespace clang } // end namespace ento diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index 45f40368ea3..45d854b0087 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -130,7 +130,7 @@ void DereferenceChecker::reportBug(ProgramStateRef State, const Stmt *S, } case Stmt::MemberExprClass: { const MemberExpr *M = cast<MemberExpr>(S); - if (M->isArrow()) { + if (M->isArrow() || bugreporter::isDeclRefExprToReference(M->getBase())) { llvm::raw_svector_ostream os(buf); os << "Access to field '" << M->getMemberNameInfo() << "' results in a dereference of a null pointer"; diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index be90de1f349..d5fe1e0a453 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -31,6 +31,13 @@ using namespace ento; // Utility functions. //===----------------------------------------------------------------------===// +bool bugreporter::isDeclRefExprToReference(const Expr *E) { + if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { + return DRE->getDecl()->getType()->isReferenceType(); + } + return false; +} + const Stmt *bugreporter::GetDerefExpr(const ExplodedNode *N) { // Pattern match for a few useful cases (do something smarter later): // a[0], p->f, *p @@ -54,7 +61,7 @@ const Stmt *bugreporter::GetDerefExpr(const ExplodedNode *N) { return U->getSubExpr()->IgnoreParenCasts(); } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(S)) { - if (ME->isArrow()) { + if (ME->isArrow() || isDeclRefExprToReference(ME->getBase())) { return ME->getBase()->IgnoreParenCasts(); } } diff --git a/clang/test/Analysis/diagnostics/deref-track-symbolic-region.cpp b/clang/test/Analysis/diagnostics/deref-track-symbolic-region.cpp new file mode 100644 index 00000000000..87313de13a8 --- /dev/null +++ b/clang/test/Analysis/diagnostics/deref-track-symbolic-region.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s + +struct S { + int *x; + int y; +}; + +S &getSomeReference(); +void test(S *p) { + S &r = *p; //expected-note {{Variable 'r' initialized here}} + if (p) return; + //expected-note@-1{{Taking false branch}} + //expected-note@-2{{Assuming pointer value is null}} + r.y = 5; // expected-warning {{Access to field 'y' results in a dereference of a null pointer (loaded from variable 'r')}} + // expected-note@-1{{Access to field 'y' results in a dereference of a null pointer (loaded from variable 'r')}} +} |

