From 6ee44e1f03996cdd09b7e72fd320789a82e45aac Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Thu, 16 Aug 2012 00:03:33 +0000 Subject: [PATCH] [analyzer] Look through all casts when trying to track constraints. Previously, we were losing path notes (in both text and plist form) because the interesting DeclRefExpr was buried in a cast. llvm-svn: 161999 --- .../Core/BugReporterVisitors.cpp | 2 +- .../test/Analysis/method-call-path-notes.cpp | 85 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 46aa9e2b9123..e7295878fa6f 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -323,7 +323,7 @@ void bugreporter::addTrackNullOrUndefValueVisitor(const ExplodedNode *N, // Walk through lvalue-to-rvalue conversions. const Expr *Ex = dyn_cast(S); if (Ex) { - Ex = Ex->IgnoreParenLValueCasts(); + Ex = Ex->IgnoreParenCasts(); if (const DeclRefExpr *DR = dyn_cast(Ex)) { if (const VarDecl *VD = dyn_cast(DR->getDecl())) { const VarRegion *R = diff --git a/clang/test/Analysis/method-call-path-notes.cpp b/clang/test/Analysis/method-call-path-notes.cpp index fbf0cae7d8a6..17034b9b0001 100644 --- a/clang/test/Analysis/method-call-path-notes.cpp +++ b/clang/test/Analysis/method-call-path-notes.cpp @@ -36,6 +36,11 @@ void test_ic_member_ptr() { (p->*bar)(); // expected-warning {{Called C++ object pointer is null}} expected-note{{Called C++ object pointer is null}} } +void test_cast(const TestInstanceCall *p) { + if (!p) // expected-note {{Assuming pointer value is null}} expected-note {{Taking true branch}} + const_cast(p)->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note {{Called C++ object pointer is null}} +} + // CHECK: // CHECK: // CHECK: @@ -659,6 +664,86 @@ void test_ic_member_ptr() { // CHECK: file0 // CHECK: // CHECK: +// CHECK: +// CHECK: path +// CHECK: +// CHECK: +// CHECK: kindcontrol +// CHECK: edges +// CHECK: +// CHECK: +// CHECK: start +// CHECK: +// CHECK: +// CHECK: line40 +// CHECK: col3 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line40 +// CHECK: col4 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: end +// CHECK: +// CHECK: +// CHECK: line41 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line41 +// CHECK: col14 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: +// CHECK: kindevent +// CHECK: location +// CHECK: +// CHECK: line41 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: ranges +// CHECK: +// CHECK: +// CHECK: +// CHECK: line41 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: line41 +// CHECK: col37 +// CHECK: file0 +// CHECK: +// CHECK: +// CHECK: +// CHECK: depth0 +// CHECK: extended_message +// CHECK: Called C++ object pointer is null +// CHECK: message +// CHECK: Called C++ object pointer is null +// CHECK: +// CHECK: +// CHECK: descriptionCalled C++ object pointer is null +// CHECK: categoryLogic error +// CHECK: typeCalled C++ object pointer is null +// CHECK: issue_context_kindfunction +// CHECK: issue_contexttest_cast +// CHECK: issue_hash2 +// CHECK: location +// CHECK: +// CHECK: line41 +// CHECK: col5 +// CHECK: file0 +// CHECK: +// CHECK: // CHECK: // CHECK: // CHECK: