[PATCH] D49570: [analyzer] Improve warning messages and notes of DanglingInternalBufferChecker

2018-08-10 Thread Reka Kovacs via Phabricator via cfe-commits
rnkovacs marked an inline comment as done.
rnkovacs added inline comments.



Comment at: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp:253
+  allocation_state::getContainerObjRegion(N->getState(), PtrToBuf);
+  const auto *TypedRegion = dyn_cast(ObjRegion);
+  QualType ObjTy = TypedRegion->getValueType();

NoQ wrote:
> `dyn_cast` may fail by returning a null pointer. This either needs to be 
> changed to `cast` or there needs to be a check for a null pointer before use. 
> I guess it should be a `cast` because you're only acting on typed regions in 
> the checker itself.
I hope that in a few more reviews I'll learn to use all of these properly.



Comment at: lib/StaticAnalyzer/Checkers/MallocChecker.cpp:2931-2932
+OS << "deallocated by call to destructor";
+StackHint = new StackHintGeneratorForSymbol(Sym,
+  "Returning; inner buffer was 
deallocated");
   } else {

NoQ wrote:
> Cool stuff!
:)



Comment at: test/Analysis/dangling-internal-buffer.cpp:63
 // expected-note@-4 {{Taking false branch}}
-consume(c); // expected-warning {{Use of memory after it is freed}}
-// expected-note@-1 {{Use of memory after it is freed}}
+consume(c); // expected-warning {{Deallocated pointer returned to the 
caller}}
+// expected-note@-1 {{Deallocated pointer returned to the caller}}

NoQ wrote:
> Mm, nono, there's no `return` statement here, so we shouldn't say that our 
> pointer is returned to the caller. Whether it should say "returned to the 
> caller" or not, should not depend on the allocation family, but on the kind 
> of "use" we encounter "after" "free".
I don't even know how this went so off, sorry.


https://reviews.llvm.org/D49570



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49570: [analyzer] Improve warning messages and notes of DanglingInternalBufferChecker

2018-08-10 Thread Reka Kovacs via Phabricator via cfe-commits
rnkovacs updated this revision to Diff 160193.
rnkovacs marked 3 inline comments as done.
rnkovacs added a comment.

Address comments & rebase.


https://reviews.llvm.org/D49570

Files:
  lib/StaticAnalyzer/Checkers/AllocationState.h
  lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
  lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  test/Analysis/inner-pointer.cpp

Index: test/Analysis/inner-pointer.cpp
===
--- test/Analysis/inner-pointer.cpp
+++ test/Analysis/inner-pointer.cpp
@@ -65,106 +65,106 @@
   const char *c, *d;
   {
 std::string s;
-c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
-d = s.data();  // expected-note {{Dangling inner pointer obtained here}}
-  }// expected-note {{Inner pointer invalidated by call to destructor}}
-  // expected-note@-1 {{Inner pointer invalidated by call to destructor}}
+c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
+d = s.data();  // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
+  }// expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}}
+  // expected-note@-1 {{Inner buffer of 'std::string' deallocated by call to destructor}}
   std::string s;
   const char *c2 = s.c_str();
   if (cond) {
 // expected-note@-1 {{Assuming 'cond' is not equal to 0}}
 // expected-note@-2 {{Taking true branch}}
 // expected-note@-3 {{Assuming 'cond' is 0}}
 // expected-note@-4 {{Taking false branch}}
-consume(c); // expected-warning {{Use of memory after it is freed}}
-// expected-note@-1 {{Use of memory after it is freed}}
+consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
+// expected-note@-1 {{Inner pointer of container used after re/deallocation}}
   } else {
-consume(d); // expected-warning {{Use of memory after it is freed}}
-// expected-note@-1 {{Use of memory after it is freed}}
+consume(d); // expected-warning {{Inner pointer of container used after re/deallocation}}
+// expected-note@-1 {{Inner pointer of container used after re/deallocation}}
   }
 }
 
 void deref_after_scope_char_data_non_const() {
   char *c;
   {
 std::string s;
-c = s.data(); // expected-note {{Dangling inner pointer obtained here}}
-  }   // expected-note {{Inner pointer invalidated by call to destructor}}
+c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' obtained here}}
+  }   // expected-note {{Inner buffer of 'std::string' deallocated by call to destructor}}
   std::string s;
   char *c2 = s.data();
-  consume(c); // expected-warning {{Use of memory after it is freed}}
-  // expected-note@-1 {{Use of memory after it is freed}}
+  consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
+  // expected-note@-1 {{Inner pointer of container used after re/deallocation}}
 }
 
 void deref_after_scope_wchar_t(bool cond) {
   const wchar_t *c, *d;
   {
 std::wstring s;
-c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
-d = s.data();  // expected-note {{Dangling inner pointer obtained here}}
-  }// expected-note {{Inner pointer invalidated by call to destructor}}
-  // expected-note@-1 {{Inner pointer invalidated by call to destructor}}
+c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::wstring' obtained here}}
+d = s.data();  // expected-note {{Pointer to inner buffer of 'std::wstring' obtained here}}
+  }// expected-note {{Inner buffer of 'std::wstring' deallocated by call to destructor}}
+  // expected-note@-1 {{Inner buffer of 'std::wstring' deallocated by call to destructor}}
   std::wstring s;
   const wchar_t *c2 = s.c_str();
   if (cond) {
 // expected-note@-1 {{Assuming 'cond' is not equal to 0}}
 // expected-note@-2 {{Taking true branch}}
 // expected-note@-3 {{Assuming 'cond' is 0}}
 // expected-note@-4 {{Taking false branch}}
-consume(c); // expected-warning {{Use of memory after it is freed}}
-// expected-note@-1 {{Use of memory after it is freed}}
+consume(c); // expected-warning {{Inner pointer of container used after re/deallocation}}
+// expected-note@-1 {{Inner pointer of container used after re/deallocation}}
   } else {
-consume(d); // expected-warning {{Use of memory after it is freed}}
-// expected-note@-1 {{Use of memory after it is freed}}
+consume(d); // expected-warning {{Inner pointer of container used after re/deallocation}}
+// expected-note@-1 {{Inner pointer of container used after re/deallocation}}
   }
 }
 
 void deref_after_scope_char16_t_cstr() {
   const char16_t *c16;
   {
 std::u16string s16;
-c16 = s16.c_str(); // expected-note {{Dangling inner pointer obtained here}}
-  }// expected-note 

[PATCH] D49570: [analyzer] Improve warning messages and notes of DanglingInternalBufferChecker

2018-07-19 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added inline comments.



Comment at: lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp:253
+  allocation_state::getContainerObjRegion(N->getState(), PtrToBuf);
+  const auto *TypedRegion = dyn_cast(ObjRegion);
+  QualType ObjTy = TypedRegion->getValueType();

`dyn_cast` may fail by returning a null pointer. This either needs to be 
changed to `cast` or there needs to be a check for a null pointer before use. I 
guess it should be a `cast` because you're only acting on typed regions in the 
checker itself.



Comment at: lib/StaticAnalyzer/Checkers/MallocChecker.cpp:2931-2932
+OS << "deallocated by call to destructor";
+StackHint = new StackHintGeneratorForSymbol(Sym,
+  "Returning; inner buffer was 
deallocated");
   } else {

Cool stuff!



Comment at: test/Analysis/dangling-internal-buffer.cpp:63
 // expected-note@-4 {{Taking false branch}}
-consume(c); // expected-warning {{Use of memory after it is freed}}
-// expected-note@-1 {{Use of memory after it is freed}}
+consume(c); // expected-warning {{Deallocated pointer returned to the 
caller}}
+// expected-note@-1 {{Deallocated pointer returned to the caller}}

Mm, nono, there's no `return` statement here, so we shouldn't say that our 
pointer is returned to the caller. Whether it should say "returned to the 
caller" or not, should not depend on the allocation family, but on the kind of 
"use" we encounter "after" "free".



Comment at: test/Analysis/dangling-internal-buffer.cpp:75
 std::string s;
-c = s.data(); // expected-note {{Dangling inner pointer obtained here}}
-  }   // expected-note {{Inner pointer invalidated by call to 
destructor}}
+c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' 
object obtained here}}
+  }   // expected-note {{Inner buffer deallocated by call to 
destructor}}

I suggest a shorter `on a 'std::string'` instead of `on 'std::string' object`.


Repository:
  rC Clang

https://reviews.llvm.org/D49570



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49570: [analyzer] Improve warning messages and notes of DanglingInternalBufferChecker

2018-07-19 Thread Reka Kovacs via Phabricator via cfe-commits
rnkovacs created this revision.
rnkovacs added reviewers: NoQ, dcoughlin, xazax.hun, george.karpenkov.
Herald added subscribers: mikhail.ramalho, a.sidorin, dkrupp, szepet, 
baloghadamsoftware, whisperity.

Following the discussion at https://reviews.llvm.org/D49360.
Added two more test cases that show "returning"-type-of notes as well.


Repository:
  rC Clang

https://reviews.llvm.org/D49570

Files:
  lib/StaticAnalyzer/Checkers/AllocationState.h
  lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
  lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  test/Analysis/dangling-internal-buffer.cpp

Index: test/Analysis/dangling-internal-buffer.cpp
===
--- test/Analysis/dangling-internal-buffer.cpp
+++ test/Analysis/dangling-internal-buffer.cpp
@@ -49,232 +49,264 @@
   const char *c, *d;
   {
 std::string s;
-c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
-d = s.data();  // expected-note {{Dangling inner pointer obtained here}}
-  }// expected-note {{Inner pointer invalidated by call to destructor}}
-  // expected-note@-1 {{Inner pointer invalidated by call to destructor}}
+c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::string' object obtained here}}
+d = s.data();  // expected-note {{Pointer to inner buffer of 'std::string' object obtained here}}
+  }// expected-note {{Inner buffer deallocated by call to destructor}}
+  // expected-note@-1 {{Inner buffer deallocated by call to destructor}}
   std::string s;
   const char *c2 = s.c_str();
   if (cond) {
 // expected-note@-1 {{Assuming 'cond' is not equal to 0}}
 // expected-note@-2 {{Taking true branch}}
 // expected-note@-3 {{Assuming 'cond' is 0}}
 // expected-note@-4 {{Taking false branch}}
-consume(c); // expected-warning {{Use of memory after it is freed}}
-// expected-note@-1 {{Use of memory after it is freed}}
+consume(c); // expected-warning {{Deallocated pointer returned to the caller}}
+// expected-note@-1 {{Deallocated pointer returned to the caller}}
   } else {
-consume(d); // expected-warning {{Use of memory after it is freed}}
-// expected-note@-1 {{Use of memory after it is freed}}
+consume(d); // expected-warning {{Deallocated pointer returned to the caller}}
+// expected-note@-1 {{Deallocated pointer returned to the caller}}
   }
 }
 
 void deref_after_scope_char_data_non_const() {
   char *c;
   {
 std::string s;
-c = s.data(); // expected-note {{Dangling inner pointer obtained here}}
-  }   // expected-note {{Inner pointer invalidated by call to destructor}}
+c = s.data(); // expected-note {{Pointer to inner buffer of 'std::string' object obtained here}}
+  }   // expected-note {{Inner buffer deallocated by call to destructor}}
   std::string s;
   char *c2 = s.data();
-  consume(c); // expected-warning {{Use of memory after it is freed}}
-  // expected-note@-1 {{Use of memory after it is freed}}
+  consume(c); // expected-warning {{Deallocated pointer returned to the caller}}
+  // expected-note@-1 {{Deallocated pointer returned to the caller}}
 }
 
 void deref_after_scope_wchar_t(bool cond) {
   const wchar_t *c, *d;
   {
 std::wstring s;
-c = s.c_str(); // expected-note {{Dangling inner pointer obtained here}}
-d = s.data();  // expected-note {{Dangling inner pointer obtained here}}
-  }// expected-note {{Inner pointer invalidated by call to destructor}}
-  // expected-note@-1 {{Inner pointer invalidated by call to destructor}}
+c = s.c_str(); // expected-note {{Pointer to inner buffer of 'std::wstring' object obtained here}}
+d = s.data();  // expected-note {{Pointer to inner buffer of 'std::wstring' object obtained here}}
+  }// expected-note {{Inner buffer deallocated by call to destructor}}
+  // expected-note@-1 {{Inner buffer deallocated by call to destructor}}
   std::wstring s;
   const wchar_t *c2 = s.c_str();
   if (cond) {
 // expected-note@-1 {{Assuming 'cond' is not equal to 0}}
 // expected-note@-2 {{Taking true branch}}
 // expected-note@-3 {{Assuming 'cond' is 0}}
 // expected-note@-4 {{Taking false branch}}
-consume(c); // expected-warning {{Use of memory after it is freed}}
-// expected-note@-1 {{Use of memory after it is freed}}
+consume(c); // expected-warning {{Deallocated pointer returned to the caller}}
+// expected-note@-1 {{Deallocated pointer returned to the caller}}
   } else {
-consume(d); // expected-warning {{Use of memory after it is freed}}
-// expected-note@-1 {{Use of memory after it is freed}}
+consume(d); // expected-warning {{Deallocated pointer returned to the caller}}
+// expected-note@-1 {{Deallocated pointer returned to the caller}}
   }
 }
 
 void deref_after_scope_char16_t_cstr() {
   const char16_t *c16;
   {
 std::u16string s16;
-c16 =