From 1e1d011874340f33b807ac90609424f90f72488a Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Wed, 17 Apr 2013 23:17:43 +0000 Subject: [PATCH] [analyzer] Improve dereferenced expression tracking for MemberExpr with a dot and non-reference base git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179734 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Core/BugReporterVisitors.cpp | 4 + test/Analysis/inlining/path-notes.cpp | 274 ++++++++++++++++++ 2 files changed, 278 insertions(+) diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 7a0d370b81..9cf39d1e96 100644 --- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -61,6 +61,10 @@ const Expr *bugreporter::getDerefExpr(const Stmt *S) { else if (const MemberExpr *ME = dyn_cast(E)) { if (ME->isArrow() || isDeclRefExprToReference(ME->getBase())) { return ME->getBase()->IgnoreParenCasts(); + } else { + // If we have a member expr with a dot, the base must have been + // dereferenced. + return getDerefExpr(ME->getBase()); } } else if (const ObjCIvarRefExpr *IvarRef = dyn_cast(E)) { diff --git a/test/Analysis/inlining/path-notes.cpp b/test/Analysis/inlining/path-notes.cpp index 01af5313b1..b090b68fd6 100644 --- a/test/Analysis/inlining/path-notes.cpp +++ b/test/Analysis/inlining/path-notes.cpp @@ -222,6 +222,28 @@ void test(Derived d) { // expected-note@-1 {{Dereference of null pointer (loaded from field 'x')}} } +struct Owner { + struct Wrapper { + int x; + }; + Wrapper *arr; + void testGetDerefExprOnMemberExprWithADot(); +}; + +void Owner::testGetDerefExprOnMemberExprWithADot() { + if (arr) // expected-note {{Assuming pointer value is null}} + // expected-note@-1 {{Taking false branch}} + ; + arr[1].x = 1; //expected-warning {{Dereference of null pointer}} + //expected-note@-1 {{Dereference of null pointer}} +} + +void testGetDerefExprOnMemberExprWithADot() { + Owner::Wrapper *arr; // expected-note {{'arr' declared without an initial value}} + arr[2].x = 1; // expected-warning {{Dereference of undefined pointer value}} + // expected-note@-1 {{Dereference of undefined pointer value}} +} + // CHECK: diagnostics // CHECK-NEXT: // CHECK-NEXT: @@ -3937,4 +3959,256 @@ void test(Derived d) { // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: path +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line234 +// CHECK-NEXT: col2 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line234 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line234 +// CHECK-NEXT: col6 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line234 +// CHECK-NEXT: col8 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line234 +// CHECK-NEXT: col6 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line234 +// CHECK-NEXT: col6 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line234 +// CHECK-NEXT: col8 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Assuming pointer value is null +// CHECK-NEXT: message +// CHECK-NEXT: Assuming pointer value is null +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line234 +// CHECK-NEXT: col6 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line234 +// CHECK-NEXT: col8 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line237 +// CHECK-NEXT: col2 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line237 +// CHECK-NEXT: col4 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line237 +// CHECK-NEXT: col2 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line237 +// CHECK-NEXT: col2 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line237 +// CHECK-NEXT: col13 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Dereference of null pointer +// CHECK-NEXT: message +// CHECK-NEXT: Dereference of null pointer +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: descriptionDereference of null pointer +// CHECK-NEXT: categoryLogic error +// CHECK-NEXT: typeDereference of null pointer +// CHECK-NEXT: issue_context_kindC++ method +// CHECK-NEXT: issue_contexttestGetDerefExprOnMemberExprWithADot +// CHECK-NEXT: issue_hash4 +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line237 +// CHECK-NEXT: col2 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: path +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line242 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line242 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line242 +// CHECK-NEXT: col21 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: 'arr' declared without an initial value +// CHECK-NEXT: message +// CHECK-NEXT: 'arr' declared without an initial value +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line242 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line242 +// CHECK-NEXT: col7 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line243 +// CHECK-NEXT: col2 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line243 +// CHECK-NEXT: col4 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line243 +// CHECK-NEXT: col2 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line243 +// CHECK-NEXT: col2 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line243 +// CHECK-NEXT: col13 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Dereference of undefined pointer value +// CHECK-NEXT: message +// CHECK-NEXT: Dereference of undefined pointer value +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: descriptionDereference of undefined pointer value +// CHECK-NEXT: categoryLogic error +// CHECK-NEXT: typeDereference of undefined pointer value +// CHECK-NEXT: issue_context_kindfunction +// CHECK-NEXT: issue_contexttestGetDerefExprOnMemberExprWithADot +// CHECK-NEXT: issue_hash2 +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line243 +// CHECK-NEXT: col2 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: // CHECK-NEXT: -- 2.40.0