r339489 - [analyzer] InnerPointerChecker: improve warning messages and notes.

2018-08-10 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Fri Aug 10 16:56:57 2018
New Revision: 339489

URL: http://llvm.org/viewvc/llvm-project?rev=339489=rev
Log:
[analyzer] InnerPointerChecker: improve warning messages and notes.

Differential Revision: https://reviews.llvm.org/D49570

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

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h?rev=339489=339488=339489=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h Fri Aug 10 16:56:57 
2018
@@ -26,6 +26,11 @@ ProgramStateRef markReleased(ProgramStat
 /// AF_InnerBuffer symbols.
 std::unique_ptr getInnerPointerBRVisitor(SymbolRef Sym);
 
+/// 'Sym' represents a pointer to the inner buffer of a container object.
+/// This function looks up the memory region of that object in
+/// DanglingInternalBufferChecker's program state map.
+const MemRegion *getContainerObjRegion(ProgramStateRef State, SymbolRef Sym);
+
 } // end namespace allocation_state
 
 } // end namespace ento

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp?rev=339489=339488=339489=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp Fri Aug 10 
16:56:57 2018
@@ -279,6 +279,28 @@ void InnerPointerChecker::checkDeadSymbo
   C.addTransition(State);
 }
 
+namespace clang {
+namespace ento {
+namespace allocation_state {
+
+std::unique_ptr getInnerPointerBRVisitor(SymbolRef Sym) {
+  return llvm::make_unique(Sym);
+}
+
+const MemRegion *getContainerObjRegion(ProgramStateRef State, SymbolRef Sym) {
+  RawPtrMapTy Map = State->get();
+  for (const auto Entry : Map) {
+if (Entry.second.contains(Sym)) {
+  return Entry.first;
+}
+  }
+  return nullptr;
+}
+
+} // end namespace allocation_state
+} // end namespace ento
+} // end namespace clang
+
 std::shared_ptr
 InnerPointerChecker::InnerPointerBRVisitor::VisitNode(const ExplodedNode *N,
   const ExplodedNode 
*PrevN,
@@ -292,27 +314,21 @@ InnerPointerChecker::InnerPointerBRVisit
   if (!S)
 return nullptr;
 
+  const MemRegion *ObjRegion =
+  allocation_state::getContainerObjRegion(N->getState(), PtrToBuf);
+  const auto *TypedRegion = cast(ObjRegion);
+  QualType ObjTy = TypedRegion->getValueType();
+
   SmallString<256> Buf;
   llvm::raw_svector_ostream OS(Buf);
-  OS << "Dangling inner pointer obtained here";
+  OS << "Pointer to inner buffer of '" << ObjTy.getAsString()
+ << "' obtained here";
   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
  N->getLocationContext());
   return std::make_shared(Pos, OS.str(), true,
 nullptr);
 }
 
-namespace clang {
-namespace ento {
-namespace allocation_state {
-
-std::unique_ptr getInnerPointerBRVisitor(SymbolRef Sym) {
-  return llvm::make_unique(Sym);
-}
-
-} // end namespace allocation_state
-} // end namespace ento
-} // end namespace clang
-
 void ento::registerInnerPointerChecker(CheckerManager ) {
   registerInnerPointerCheckerAux(Mgr);
   Mgr.registerChecker();

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=339489=339488=339489=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Fri Aug 10 16:56:57 
2018
@@ -1996,15 +1996,20 @@ void MallocChecker::ReportUseAfterFree(C
   BT_UseFree[*CheckKind].reset(new BugType(
   CheckNames[*CheckKind], "Use-after-free", categories::MemoryError));
 
+AllocationFamily AF =
+C.getState()->get(Sym)->getAllocationFamily();
+
 auto R = llvm::make_unique(*BT_UseFree[*CheckKind],
- "Use of memory after it is freed", N);
+AF == AF_InnerBuffer
+  ? "Inner pointer of container used after re/deallocation"
+  : "Use of memory after it is freed",
+N);
 
 R->markInteresting(Sym);
 R->addRange(Range);
 R->addVisitor(llvm::make_unique(Sym));
 
-const RefState *RS = C.getState()->get(Sym);
-if (RS->getAllocationFamily() == AF_InnerBuffer)
+if 

r339067 - [analyzer] InnerPointerChecker: fix displayed checker name.

2018-08-06 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Mon Aug  6 15:03:42 2018
New Revision: 339067

URL: http://llvm.org/viewvc/llvm-project?rev=339067=rev
Log:
[analyzer] InnerPointerChecker: fix displayed checker name.

For InnerPointerChecker to function properly, both the checker itself
and parts of MallocChecker that handle relevant use-after-free problems
need to be turned on. So far, the latter part has been developed within
MallocChecker's NewDelete sub-checker, often causing warnings to appear
under that name. This patch defines a new CheckKind within MallocChecker
for the inner pointer checking functionality, so that the correct name
is displayed in warnings and in the ExplodedGraph.

Tested on clang-tidy.

Differential Review: https://reviews.llvm.org/D50211

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp?rev=339067=339066=339067=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp Mon Aug  6 
15:03:42 2018
@@ -15,6 +15,7 @@
 
 #include "AllocationState.h"
 #include "ClangSACheckers.h"
+#include "InterCheckerAPI.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
@@ -313,6 +314,6 @@ std::unique_ptr getI
 } // end namespace clang
 
 void ento::registerInnerPointerChecker(CheckerManager ) {
-  registerNewDeleteChecker(Mgr);
+  registerInnerPointerCheckerAux(Mgr);
   Mgr.registerChecker();
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h?rev=339067=339066=339067=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/InterCheckerAPI.h Mon Aug  6 15:03:42 
2018
@@ -20,5 +20,8 @@ namespace ento {
 /// Register the checker which evaluates CString API calls.
 void registerCStringCheckerBasic(CheckerManager );
 
+/// Register the part of MallocChecker connected to InnerPointerChecker.
+void registerInnerPointerCheckerAux(CheckerManager );
+
 }}
 #endif /* INTERCHECKERAPI_H_ */

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=339067=339066=339067=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Mon Aug  6 15:03:42 
2018
@@ -194,6 +194,7 @@ public:
 CK_NewDeleteChecker,
 CK_NewDeleteLeaksChecker,
 CK_MismatchedDeallocatorChecker,
+CK_InnerPointerChecker,
 CK_NumCheckKinds
   };
 
@@ -1662,13 +1663,10 @@ MallocChecker::getCheckIfTracked(Allocat
   case AF_IfNameIndex: {
 if (ChecksEnabled[CK_MallocChecker])
   return CK_MallocChecker;
-
-return Optional();
+return None;
   }
   case AF_CXXNew:
-  case AF_CXXNewArray:
-  // FIXME: Add new CheckKind for AF_InnerBuffer.
-  case AF_InnerBuffer: {
+  case AF_CXXNewArray: {
 if (IsALeakCheck) {
   if (ChecksEnabled[CK_NewDeleteLeaksChecker])
 return CK_NewDeleteLeaksChecker;
@@ -1677,7 +1675,12 @@ MallocChecker::getCheckIfTracked(Allocat
   if (ChecksEnabled[CK_NewDeleteChecker])
 return CK_NewDeleteChecker;
 }
-return Optional();
+return None;
+  }
+  case AF_InnerBuffer: {
+if (ChecksEnabled[CK_InnerPointerChecker])
+  return CK_InnerPointerChecker;
+return None;
   }
   case AF_None: {
 llvm_unreachable("no family");
@@ -1980,7 +1983,8 @@ void MallocChecker::ReportUseAfterFree(C
SymbolRef Sym) const {
 
   if (!ChecksEnabled[CK_MallocChecker] &&
-  !ChecksEnabled[CK_NewDeleteChecker])
+  !ChecksEnabled[CK_NewDeleteChecker] &&
+  !ChecksEnabled[CK_InnerPointerChecker])
 return;
 
   Optional CheckKind = getCheckIfTracked(C, Sym);
@@ -3109,6 +3113,18 @@ void ento::registerNewDeleteLeaksChecker
   }
 }
 
+// Intended to be used in InnerPointerChecker to register the part of
+// MallocChecker connected to it.
+void ento::registerInnerPointerCheckerAux(CheckerManager ) {
+registerCStringCheckerBasic(mgr);
+MallocChecker *checker = mgr.registerChecker();
+checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption(
+"Optimistic", false, checker);
+

r338918 - [analyzer] Add test for a crash fixed in r338775.

2018-08-03 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Fri Aug  3 13:42:02 2018
New Revision: 338918

URL: http://llvm.org/viewvc/llvm-project?rev=338918=rev
Log:
[analyzer] Add test for a crash fixed in r338775.

Do not crash if a CXXRecordDecl cannot be obtained for an object.

Special thanks for the reproduction to Alexander Kornienko.

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
cfe/trunk/test/Analysis/inner-pointer.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp?rev=338918=338917=338918=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp Fri Aug  3 
13:42:02 2018
@@ -133,10 +133,7 @@ bool InnerPointerChecker::isCalledOnStri
 return false;
 
   CXXRecordDecl *Decl = ObjTy->getAsCXXRecordDecl();
-  if (!Decl || Decl->getName() != "basic_string")
-return false;
-
-  return true;
+  return Decl && Decl->getName() == "basic_string";
 }
 
 bool InnerPointerChecker::isInvalidatingMemberFunction(

Modified: cfe/trunk/test/Analysis/inner-pointer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inner-pointer.cpp?rev=338918=338917=338918=diff
==
--- cfe/trunk/test/Analysis/inner-pointer.cpp (original)
+++ cfe/trunk/test/Analysis/inner-pointer.cpp Fri Aug  3 13:42:02 2018
@@ -382,3 +382,13 @@ const char *escape_via_return_local() {
 // expected-note@-1 {{Inner pointer invalidated by call to 
destructor}}
 } // expected-warning {{Use of memory after it is freed}}
 // expected-note@-1 {{Use of memory after it is freed}}
+
+
+char *c();
+class A {};
+
+void no_CXXRecordDecl() {
+  A a, *b;
+  *(void **) = c() + 1;
+  *b = a; // no-crash
+}


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


r338780 - [analyzer] Detect pointers escaped after ReturnStmt execution in MallocChecker.

2018-08-02 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Thu Aug  2 16:02:08 2018
New Revision: 338780

URL: http://llvm.org/viewvc/llvm-project?rev=338780=rev
Log:
[analyzer] Detect pointers escaped after ReturnStmt execution in MallocChecker.

Objects local to a function are destroyed right after the statement returning
(part of) them is executed in the analyzer. This patch enables MallocChecker to
warn in these cases.

Differential Revision: https://reviews.llvm.org/D49361

Added:
cfe/trunk/test/Analysis/malloc-free-after-return.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/test/Analysis/inner-pointer.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=338780=338779=338780=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Thu Aug  2 16:02:08 
2018
@@ -161,6 +161,7 @@ class MallocChecker : public Checker,
+ check::EndFunction,
  check::PreCall,
  check::PostStmt,
  check::PostStmt,
@@ -217,6 +218,7 @@ public:
   void checkPostStmt(const BlockExpr *BE, CheckerContext ) const;
   void checkDeadSymbols(SymbolReaper , CheckerContext ) const;
   void checkPreStmt(const ReturnStmt *S, CheckerContext ) const;
+  void checkEndFunction(const ReturnStmt *S, CheckerContext ) const;
   ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
 bool Assumption) const;
   void checkLocation(SVal l, bool isLoad, const Stmt *S,
@@ -353,7 +355,7 @@ private:
   static ProgramStateRef CallocMem(CheckerContext , const CallExpr *CE,
ProgramStateRef State);
 
-  ///Check if the memory associated with this symbol was released.
+  /// Check if the memory associated with this symbol was released.
   bool isReleased(SymbolRef Sym, CheckerContext ) const;
 
   bool checkUseAfterFree(SymbolRef Sym, CheckerContext , const Stmt *S) 
const;
@@ -377,13 +379,16 @@ private:
ProgramStateRef State,
SymbolRef ) const;
 
-  // Implementation of the checkPointerEscape callabcks.
+  // Implementation of the checkPointerEscape callbacks.
   ProgramStateRef checkPointerEscapeAux(ProgramStateRef State,
   const InvalidatedSymbols ,
   const CallEvent *Call,
   PointerEscapeKind Kind,
   bool(*CheckRefState)(const RefState*)) const;
 
+  // Implementation of the checkPreStmt and checkEndFunction callbacks.
+  void checkEscapeOnReturn(const ReturnStmt *S, CheckerContext ) const;
+
   ///@{
   /// Tells if a given family/call/symbol is tracked by the current checker.
   /// Sets CheckKind to the kind of the checker responsible for this
@@ -2451,7 +2456,24 @@ void MallocChecker::checkPreCall(const C
   }
 }
 
-void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext ) const 
{
+void MallocChecker::checkPreStmt(const ReturnStmt *S,
+ CheckerContext ) const {
+  checkEscapeOnReturn(S, C);
+}
+
+// In the CFG, automatic destructors come after the return statement.
+// This callback checks for returning memory that is freed by automatic
+// destructors, as those cannot be reached in checkPreStmt().
+void MallocChecker::checkEndFunction(const ReturnStmt *S,
+ CheckerContext ) const {
+  checkEscapeOnReturn(S, C);
+}
+
+void MallocChecker::checkEscapeOnReturn(const ReturnStmt *S,
+CheckerContext ) const {
+  if (!S)
+return;
+
   const Expr *E = S->getRetValue();
   if (!E)
 return;

Modified: cfe/trunk/test/Analysis/inner-pointer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inner-pointer.cpp?rev=338780=338779=338780=diff
==
--- cfe/trunk/test/Analysis/inner-pointer.cpp (original)
+++ cfe/trunk/test/Analysis/inner-pointer.cpp Thu Aug  2 16:02:08 2018
@@ -361,3 +361,24 @@ void func_default_arg() {
   consume(c);// expected-warning {{Use of memory after it is freed}}
   // expected-note@-1 {{Use of memory after it is freed}}
 }
+
+struct S {
+  std::string to_string() { return s; }
+private:
+  std::string s;
+};
+
+const char *escape_via_return_temp() {
+  S x;
+  return x.to_string().c_str(); // expected-note {{Dangling inner pointer 
obtained here}}
+  // expected-note@-1 {{Inner pointer invalidated by call to destructor}}
+  // expected-warning@-2 {{Use of memory after it is freed}}
+  // expected-note@-3 {{Use of memory after 

r338777 - [analyzer] Obtain a ReturnStmt from a CFGAutomaticObjDtor.

2018-08-02 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Thu Aug  2 15:31:03 2018
New Revision: 338777

URL: http://llvm.org/viewvc/llvm-project?rev=338777=rev
Log:
[analyzer] Obtain a ReturnStmt from a CFGAutomaticObjDtor.

The CoreEngine only gives us a ReturnStmt if the last element in the
CFGBlock is a CFGStmt, otherwise the ReturnStmt is nullptr.
This patch adds support for the case when the last element is a
CFGAutomaticObjDtor, by returning its TriggerStmt as a ReturnStmt.

Differential Revision: https://reviews.llvm.org/D49811

Added:
cfe/trunk/test/Analysis/end-function-return-stmt.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp?rev=338777=338776=338777=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp Thu Aug  2 
15:31:03 2018
@@ -16,6 +16,7 @@
 
 #include "ClangSACheckers.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/Analysis/CFGStmtMap.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
@@ -37,6 +38,7 @@ class AnalysisOrderChecker
  check::PostStmt,
  check::PreCall,
  check::PostCall,
+ check::EndFunction,
  check::NewAllocator,
  check::Bind,
  check::RegionChanges,
@@ -121,6 +123,23 @@ public:
 }
   }
 
+  void checkEndFunction(const ReturnStmt *S, CheckerContext ) const {
+if (isCallbackEnabled(C, "EndFunction")) {
+  llvm::errs() << "EndFunction\nReturnStmt: " << (S ? "yes" : "no") << 
"\n";
+  if (!S)
+return;
+
+  llvm::errs() << "CFGElement: ";
+  CFGStmtMap *Map = C.getCurrentAnalysisDeclContext()->getCFGStmtMap();
+  CFGElement LastElement = Map->getBlock(S)->back();
+
+  if (LastElement.getAs())
+llvm::errs() << "CFGStmt\n";
+  else if (LastElement.getAs())
+llvm::errs() << "CFGAutomaticObjDtor\n";
+}
+  }
+
   void checkNewAllocator(const CXXNewExpr *CNE, SVal Target,
  CheckerContext ) const {
 if (isCallbackEnabled(C, "NewAllocator"))

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=338777=338776=338777=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Thu Aug  2 15:31:03 2018
@@ -223,8 +223,12 @@ void CoreEngine::HandleBlockEdge(const B
 // Get return statement..
 const ReturnStmt *RS = nullptr;
 if (!L.getSrc()->empty()) {
-  if (Optional LastStmt = L.getSrc()->back().getAs()) {
+  CFGElement LastElement = L.getSrc()->back();
+  if (Optional LastStmt = LastElement.getAs()) {
 RS = dyn_cast(LastStmt->getStmt());
+  } else if (Optional AutoDtor =
+ LastElement.getAs()) {
+RS = dyn_cast(AutoDtor->getTriggerStmt());
   }
 }
 

Added: cfe/trunk/test/Analysis/end-function-return-stmt.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/end-function-return-stmt.cpp?rev=338777=auto
==
--- cfe/trunk/test/Analysis/end-function-return-stmt.cpp (added)
+++ cfe/trunk/test/Analysis/end-function-return-stmt.cpp Thu Aug  2 15:31:03 
2018
@@ -0,0 +1,34 @@
+//RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder 
-analyzer-config debug.AnalysisOrder:EndFunction=true %s 2>&1 | FileCheck %s
+
+// At the end of a function, we can only obtain a ReturnStmt if the last
+// CFGElement in the CFGBlock is either a CFGStmt or a CFGAutomaticObjDtor.
+
+void noReturnStmt() {}
+
+struct S {
+  S();
+  ~S();
+};
+
+int dtorAfterReturnStmt() {
+  S s;
+  return 0;
+}
+
+S endsWithReturnStmt() {
+  return S();
+}
+
+// endsWithReturnStmt()
+// CHECK:  EndFunction
+// CHECK-NEXT: ReturnStmt: yes
+// CHECK-NEXT: CFGElement: CFGStmt
+
+// dtorAfterReturnStmt()
+// CHECK:  EndFunction
+// CHECK-NEXT: ReturnStmt: yes
+// CHECK-NEXT: CFGElement: CFGAutomaticObjDtor
+
+// noReturnStmt()
+// CHECK:  EndFunction
+// CHECK-NEXT: ReturnStmt: no


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


r338775 - [analyzer] Add a safety check to InnerPointerChecker.

2018-08-02 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Thu Aug  2 15:19:57 2018
New Revision: 338775

URL: http://llvm.org/viewvc/llvm-project?rev=338775=rev
Log:
[analyzer] Add a safety check to InnerPointerChecker.

Do not crash if the CXXRecordDecl of an object is not available.

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp?rev=338775=338774=338775=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp Thu Aug  2 
15:19:57 2018
@@ -129,8 +129,11 @@ bool InnerPointerChecker::isCalledOnStri
 return false;
 
   QualType ObjTy = ObjRegion->getValueType();
-  if (ObjTy.isNull() ||
-  ObjTy->getAsCXXRecordDecl()->getName() != "basic_string")
+  if (ObjTy.isNull())
+return false;
+
+  CXXRecordDecl *Decl = ObjTy->getAsCXXRecordDecl();
+  if (!Decl || Decl->getName() != "basic_string")
 return false;
 
   return true;


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


r338433 - [analyzer] Move InnerPointerChecker out of alpha.

2018-07-31 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Tue Jul 31 13:27:11 2018
New Revision: 338433

URL: http://llvm.org/viewvc/llvm-project?rev=338433=rev
Log:
[analyzer] Move InnerPointerChecker out of alpha.

Differential Revision: https://reviews.llvm.org/D49058

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/test/Analysis/inner-pointer.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=338433=338432=338433=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Tue Jul 31 
13:27:11 2018
@@ -276,6 +276,10 @@ def ReturnUndefChecker : Checker<"UndefR
 
 let ParentPackage = Cplusplus in {
 
+def InnerPointerChecker : Checker<"InnerPointer">,
+  HelpText<"Check for inner pointers of C++ containers used after 
re/deallocation">,
+  DescFile<"InnerPointerChecker.cpp">;
+
 def NewDeleteChecker : Checker<"NewDelete">,
   HelpText<"Check for double-free and use-after-free problems. Traces memory 
managed by new/delete.">,
   DescFile<"MallocChecker.cpp">;
@@ -305,10 +309,6 @@ def DeleteWithNonVirtualDtorChecker : Ch
"destructor in their base class">,
   DescFile<"DeleteWithNonVirtualDtorChecker.cpp">;
 
-def InnerPointerChecker : Checker<"InnerPointer">,
-  HelpText<"Check for inner pointers of C++ containers used after 
re/deallocation">,
-  DescFile<"InnerPointerChecker.cpp">;
-
 def IteratorRangeChecker : Checker<"IteratorRange">,
   HelpText<"Check for iterators used outside their valid ranges">,
   DescFile<"IteratorChecker.cpp">;

Modified: cfe/trunk/test/Analysis/inner-pointer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inner-pointer.cpp?rev=338433=338432=338433=diff
==
--- cfe/trunk/test/Analysis/inner-pointer.cpp (original)
+++ cfe/trunk/test/Analysis/inner-pointer.cpp Tue Jul 31 13:27:11 2018
@@ -1,4 +1,4 @@
-//RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.InnerPointer %s 
-analyzer-output=text -verify
+//RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.InnerPointer %s 
-analyzer-output=text -verify
 
 namespace std {
 


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


r338263 - [analyzer] Add missing state transition in IteratorChecker.

2018-07-30 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Mon Jul 30 09:14:59 2018
New Revision: 338263

URL: http://llvm.org/viewvc/llvm-project?rev=338263=rev
Log:
[analyzer] Add missing state transition in IteratorChecker.

After cleaning up program state maps in `checkDeadSymbols()`,
a transition should be added to generate the new state.

Differential Revision: https://reviews.llvm.org/D47417

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp?rev=338263=338262=338263=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp Mon Jul 30 
09:14:59 2018
@@ -551,6 +551,8 @@ void IteratorChecker::checkDeadSymbols(S
   State = State->remove(Comp.first);
 }
   }
+
+  C.addTransition(State);
 }
 
 ProgramStateRef IteratorChecker::evalAssume(ProgramStateRef State, SVal Cond,


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


r338259 - [analyzer] Add support for more invalidating functions in InnerPointerChecker.

2018-07-30 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Mon Jul 30 08:43:45 2018
New Revision: 338259

URL: http://llvm.org/viewvc/llvm-project?rev=338259=rev
Log:
[analyzer] Add support for more invalidating functions in InnerPointerChecker.

According to the standard, pointers referring to the elements of a
`basic_string` may be invalidated if they are used as an argument to
any standard library function taking a reference to non-const
`basic_string` as an argument. This patch makes InnerPointerChecker warn
for these cases.

Differential Revision: https://reviews.llvm.org/D49656

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/test/Analysis/inner-pointer.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp?rev=338259=338258=338259=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp Mon Jul 30 
08:43:45 2018
@@ -91,37 +91,53 @@ public:
 ReserveFn("reserve"), ResizeFn("resize"),
 ShrinkToFitFn("shrink_to_fit"), SwapFn("swap") {}
 
-  /// Check whether the function called on the container object is a
-  /// member function that potentially invalidates pointers referring
-  /// to the objects's internal buffer.
-  bool mayInvalidateBuffer(const CallEvent ) const;
-
-  /// Record the connection between the symbol returned by c_str() and the
-  /// corresponding string object region in the ProgramState. Mark the symbol
-  /// released if the string object is destroyed.
+  /// Check if the object of this member function call is a `basic_string`.
+  bool isCalledOnStringObject(const CXXInstanceCall *ICall) const;
+
+  /// Check whether the called member function potentially invalidates
+  /// pointers referring to the container object's inner buffer.
+  bool isInvalidatingMemberFunction(const CallEvent ) const;
+
+  /// Mark pointer symbols associated with the given memory region released
+  /// in the program state.
+  void markPtrSymbolsReleased(const CallEvent , ProgramStateRef State,
+  const MemRegion *ObjRegion,
+  CheckerContext ) const;
+
+  /// Standard library functions that take a non-const `basic_string` argument 
by
+  /// reference may invalidate its inner pointers. Check for these cases and
+  /// mark the pointers released.
+  void checkFunctionArguments(const CallEvent , ProgramStateRef State,
+  CheckerContext ) const;
+
+  /// Record the connection between raw pointers referring to a container
+  /// object's inner buffer and the object's memory region in the program 
state.
+  /// Mark potentially invalidated pointers released.
   void checkPostCall(const CallEvent , CheckerContext ) const;
 
-  /// Clean up the ProgramState map.
+  /// Clean up the program state map.
   void checkDeadSymbols(SymbolReaper , CheckerContext ) const;
 };
 
 } // end anonymous namespace
 
-// [string.require]
-//
-// "References, pointers, and iterators referring to the elements of a
-// basic_string sequence may be invalidated by the following uses of that
-// basic_string object:
-//
-// -- TODO: As an argument to any standard library function taking a reference
-// to non-const basic_string as an argument. For example, as an argument to
-// non-member functions swap(), operator>>(), and getline(), or as an argument
-// to basic_string::swap().
-//
-// -- Calling non-const member functions, except operator[], at, front, back,
-// begin, rbegin, end, and rend."
-//
-bool InnerPointerChecker::mayInvalidateBuffer(const CallEvent ) const {
+bool InnerPointerChecker::isCalledOnStringObject(
+const CXXInstanceCall *ICall) const {
+  const auto *ObjRegion =
+dyn_cast_or_null(ICall->getCXXThisVal().getAsRegion());
+  if (!ObjRegion)
+return false;
+
+  QualType ObjTy = ObjRegion->getValueType();
+  if (ObjTy.isNull() ||
+  ObjTy->getAsCXXRecordDecl()->getName() != "basic_string")
+return false;
+
+  return true;
+}
+
+bool InnerPointerChecker::isInvalidatingMemberFunction(
+const CallEvent ) const {
   if (const auto *MemOpCall = dyn_cast()) {
 OverloadedOperatorKind Opc = MemOpCall->getOriginExpr()->getOperator();
 if (Opc == OO_Equal || Opc == OO_PlusEqual)
@@ -137,53 +153,104 @@ bool InnerPointerChecker::mayInvalidateB
   Call.isCalled(SwapFn));
 }
 
-void InnerPointerChecker::checkPostCall(const CallEvent ,
-CheckerContext ) const {
-  const auto *ICall = dyn_cast();
-  if (!ICall)
-return;
-
-  SVal Obj = ICall->getCXXThisVal();
-  const auto *ObjRegion = 
dyn_cast_or_null(Obj.getAsRegion());
-  if (!ObjRegion)
+void 

r337559 - [analyzer] Rename DanglingInternalBufferChecker to InnerPointerChecker.

2018-07-20 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Fri Jul 20 08:14:49 2018
New Revision: 337559

URL: http://llvm.org/viewvc/llvm-project?rev=337559=rev
Log:
[analyzer] Rename DanglingInternalBufferChecker to InnerPointerChecker.

Differential Revision: https://reviews.llvm.org/D49553

Added:
cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
  - copied, changed from r337555, 
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
cfe/trunk/test/Analysis/inner-pointer.cpp
  - copied, changed from r337555, 
cfe/trunk/test/Analysis/dangling-internal-buffer.cpp
Removed:
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
cfe/trunk/test/Analysis/dangling-internal-buffer.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h
cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=337559=337558=337559=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Fri Jul 20 
08:14:49 2018
@@ -300,16 +300,15 @@ def VirtualCallChecker : Checker<"Virtua
 
 let ParentPackage = CplusplusAlpha in {
 
-def DanglingInternalBufferChecker : Checker<"DanglingInternalBuffer">,
-  HelpText<"Check for internal raw pointers of C++ standard library containers 
"
-   "used after deallocation">,
-  DescFile<"DanglingInternalBufferChecker.cpp">;
-
 def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
   HelpText<"Reports destructions of polymorphic objects with a non-virtual "
"destructor in their base class">,
   DescFile<"DeleteWithNonVirtualDtorChecker.cpp">;
 
+def InnerPointerChecker : Checker<"InnerPointer">,
+  HelpText<"Check for inner pointers of C++ containers used after 
re/deallocation">,
+  DescFile<"InnerPointerChecker.cpp">;
+
 def IteratorRangeChecker : Checker<"IteratorRange">,
   HelpText<"Check for iterators used outside their valid ranges">,
   DescFile<"IteratorChecker.cpp">;

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h?rev=337559=337558=337559=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h Fri Jul 20 08:14:49 
2018
@@ -23,8 +23,8 @@ ProgramStateRef markReleased(ProgramStat
 
 /// This function provides an additional visitor that augments the bug report
 /// with information relevant to memory errors caused by the misuse of
-/// AF_InternalBuffer symbols.
-std::unique_ptr getDanglingBufferBRVisitor(SymbolRef Sym);
+/// AF_InnerBuffer symbols.
+std::unique_ptr getInnerPointerBRVisitor(SymbolRef Sym);
 
 } // end namespace allocation_state
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=337559=337558=337559=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Fri Jul 20 08:14:49 
2018
@@ -27,7 +27,6 @@ add_clang_library(clangStaticAnalyzerChe
   CloneChecker.cpp
   ConversionChecker.cpp
   CXXSelfAssignmentChecker.cpp
-  DanglingInternalBufferChecker.cpp
   DeadStoresChecker.cpp
   DebugCheckers.cpp
   DeleteWithNonVirtualDtorChecker.cpp
@@ -42,6 +41,7 @@ add_clang_library(clangStaticAnalyzerChe
   GenericTaintChecker.cpp
   GTestChecker.cpp
   IdenticalExprChecker.cpp
+  InnerPointerChecker.cpp
   IteratorChecker.cpp
   IvarInvalidationChecker.cpp
   LLVMConventionsChecker.cpp

Removed: cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp?rev=337558=auto
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp 
(removed)
@@ -1,253 +0,0 @@
-//=== DanglingInternalBufferChecker.cpp ---*- C++ 
-*--//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--===//
-//
-// 

r337474 - [analyzer] Fix memory sanitizer error in MallocChecker.

2018-07-19 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Thu Jul 19 10:43:09 2018
New Revision: 337474

URL: http://llvm.org/viewvc/llvm-project?rev=337474=rev
Log:
[analyzer] Fix memory sanitizer error in MallocChecker.

StringRef's data() returns a string that may be non-null-terminated.
Switch to using StringRefs from const char pointers in visitor notes
to avoid problems.

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=337474=337473=337474=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Thu Jul 19 10:43:09 
2018
@@ -2899,7 +2899,7 @@ std::shared_ptr Mal
   // (__attribute__((cleanup))).
 
   // Find out if this is an interesting point and what is the kind.
-  const char *Msg = nullptr;
+  StringRef Msg;
   StackHintGeneratorForSymbol *StackHint = nullptr;
   SmallString<256> Buf;
   llvm::raw_svector_ostream OS(Buf);
@@ -2933,7 +2933,7 @@ std::shared_ptr Mal
 }
 OS << "'";
   }
-  Msg = OS.str().data();
+  Msg = OS.str();
   break;
 }
 case AF_None:
@@ -3004,7 +3004,7 @@ std::shared_ptr Mal
 }
   }
 
-  if (!Msg)
+  if (Msg.empty())
 return nullptr;
   assert(StackHint);
 


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


r337466 - [analyzer] Fix disappearing notes in DanglingInternalBufferChecker tests

2018-07-19 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Thu Jul 19 08:44:46 2018
New Revision: 337466

URL: http://llvm.org/viewvc/llvm-project?rev=337466=rev
Log:
[analyzer] Fix disappearing notes in DanglingInternalBufferChecker tests

Correct a mistake of the exact same kind I am writing this checker for.

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=337466=337465=337466=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Thu Jul 19 08:44:46 
2018
@@ -2901,6 +2901,9 @@ std::shared_ptr Mal
   // Find out if this is an interesting point and what is the kind.
   const char *Msg = nullptr;
   StackHintGeneratorForSymbol *StackHint = nullptr;
+  SmallString<256> Buf;
+  llvm::raw_svector_ostream OS(Buf);
+  
   if (Mode == Normal) {
 if (isAllocated(RS, RSPrev, S)) {
   Msg = "Memory is allocated";
@@ -2917,8 +2920,6 @@ std::shared_ptr Mal
   Msg = "Memory is released";
   break;
 case AF_InternalBuffer: {
-  SmallString<256> Buf;
-  llvm::raw_svector_ostream OS(Buf);
   OS << "Inner pointer invalidated by call to ";
   if (N->getLocation().getKind() == 
ProgramPoint::PostImplicitCallKind) {
 OS << "destructor";


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


r337463 - [analyzer] Add support for more basic_string API in

2018-07-19 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Thu Jul 19 08:10:06 2018
New Revision: 337463

URL: http://llvm.org/viewvc/llvm-project?rev=337463=rev
Log:
[analyzer] Add support for more basic_string API in
DanglingInternalBufferChecker.

A pointer referring to the elements of a basic_string may be invalidated
by calling a non-const member function, except operator[], at, front,
back, begin, rbegin, end, and rend. The checker now warns if the pointer
is used after such operations.

Differential Revision: https://reviews.llvm.org/D49360

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/test/Analysis/dangling-internal-buffer.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp?rev=337463=337462=337463=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp Thu 
Jul 19 08:10:06 2018
@@ -32,8 +32,8 @@ REGISTER_MAP_WITH_PROGRAMSTATE(RawPtrMap
 // This is a trick to gain access to PtrSet's Factory.
 namespace clang {
 namespace ento {
-template<> struct ProgramStateTrait
-  : public ProgramStatePartialTrait {
+template <>
+struct ProgramStateTrait : public ProgramStatePartialTrait {
   static void *GDMIndex() {
 static int Index = 0;
 return 
@@ -46,7 +46,10 @@ namespace {
 
 class DanglingInternalBufferChecker
 : public Checker {
-  CallDescription CStrFn, DataFn;
+
+  CallDescription AppendFn, AssignFn, ClearFn, CStrFn, DataFn, EraseFn,
+  InsertFn, PopBackFn, PushBackFn, ReplaceFn, ReserveFn, ResizeFn,
+  ShrinkToFitFn, SwapFn;
 
 public:
   class DanglingBufferBRVisitor : public BugReporterVisitor {
@@ -81,7 +84,17 @@ public:
 }
   };
 
-  DanglingInternalBufferChecker() : CStrFn("c_str"), DataFn("data") {}
+  DanglingInternalBufferChecker()
+  : AppendFn("append"), AssignFn("assign"), ClearFn("clear"),
+CStrFn("c_str"), DataFn("data"), EraseFn("erase"), InsertFn("insert"),
+PopBackFn("pop_back"), PushBackFn("push_back"), ReplaceFn("replace"),
+ReserveFn("reserve"), ResizeFn("resize"),
+ShrinkToFitFn("shrink_to_fit"), SwapFn("swap") {}
+
+  /// Check whether the function called on the container object is a
+  /// member function that potentially invalidates pointers referring
+  /// to the objects's internal buffer.
+  bool mayInvalidateBuffer(const CallEvent ) const;
 
   /// Record the connection between the symbol returned by c_str() and the
   /// corresponding string object region in the ProgramState. Mark the symbol
@@ -94,6 +107,37 @@ public:
 
 } // end anonymous namespace
 
+// [string.require]
+//
+// "References, pointers, and iterators referring to the elements of a
+// basic_string sequence may be invalidated by the following uses of that
+// basic_string object:
+//
+// -- TODO: As an argument to any standard library function taking a reference
+// to non-const basic_string as an argument. For example, as an argument to
+// non-member functions swap(), operator>>(), and getline(), or as an argument
+// to basic_string::swap().
+//
+// -- Calling non-const member functions, except operator[], at, front, back,
+// begin, rbegin, end, and rend."
+//
+bool DanglingInternalBufferChecker::mayInvalidateBuffer(
+const CallEvent ) const {
+  if (const auto *MemOpCall = dyn_cast()) {
+OverloadedOperatorKind Opc = MemOpCall->getOriginExpr()->getOperator();
+if (Opc == OO_Equal || Opc == OO_PlusEqual)
+  return true;
+return false;
+  }
+  return (isa(Call) || Call.isCalled(AppendFn) ||
+  Call.isCalled(AssignFn) || Call.isCalled(ClearFn) ||
+  Call.isCalled(EraseFn) || Call.isCalled(InsertFn) ||
+  Call.isCalled(PopBackFn) || Call.isCalled(PushBackFn) ||
+  Call.isCalled(ReplaceFn) || Call.isCalled(ReserveFn) ||
+  Call.isCalled(ResizeFn) || Call.isCalled(ShrinkToFitFn) ||
+  Call.isCalled(SwapFn));
+}
+
 void DanglingInternalBufferChecker::checkPostCall(const CallEvent ,
   CheckerContext ) const {
   const auto *ICall = dyn_cast();
@@ -127,7 +171,7 @@ void DanglingInternalBufferChecker::chec
 return;
   }
 
-  if (isa(ICall)) {
+  if (mayInvalidateBuffer(Call)) {
 if (const PtrSet *PS = State->get(ObjRegion)) {
   // Mark all pointer symbols associated with the deleted object released.
   const Expr *Origin = Call.getOriginExpr();
@@ -161,8 +205,8 @@ void DanglingInternalBufferChecker::chec
   CleanedUpSet = F.remove(CleanedUpSet, Symbol);
   }
   State = CleanedUpSet.isEmpty()
-  ? State->remove(Entry.first)
-  : State->set(Entry.first, CleanedUpSet);
+   

r337215 - [analyzer] Make checkEndFunction() give access to the return statement.

2018-07-16 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Mon Jul 16 13:47:45 2018
New Revision: 337215

URL: http://llvm.org/viewvc/llvm-project?rev=337215=rev
Log:
[analyzer] Make checkEndFunction() give access to the return statement.

Differential Revision: https://reviews.llvm.org/D49387

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h?rev=337215=337214=337215=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h Mon Jul 16 13:47:45 
2018
@@ -254,9 +254,9 @@ public:
 
 class EndFunction {
   template 
-  static void _checkEndFunction(void *checker,
+  static void _checkEndFunction(void *checker, const ReturnStmt *RS,
 CheckerContext ) {
-((const CHECKER *)checker)->checkEndFunction(C);
+((const CHECKER *)checker)->checkEndFunction(RS, C);
   }
 
 public:

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=337215=337214=337215=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Mon Jul 16 
13:47:45 2018
@@ -296,7 +296,8 @@ public:
   void runCheckersForEndFunction(NodeBuilderContext ,
  ExplodedNodeSet ,
  ExplodedNode *Pred,
- ExprEngine );
+ ExprEngine ,
+ const ReturnStmt *RS);
 
   /// Run checkers for branch condition.
   void runCheckersForBranchCondition(const Stmt *condition,
@@ -438,7 +439,8 @@ public:
 
   using CheckBeginFunctionFunc = CheckerFn;
 
-  using CheckEndFunctionFunc = CheckerFn;
+  using CheckEndFunctionFunc =
+  CheckerFn;
   
   using CheckBranchConditionFunc =
   CheckerFn;
@@ -496,7 +498,7 @@ public:
 
   void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
 
-  void _registerForBeginFunction(CheckEndFunctionFunc checkfn);
+  void _registerForBeginFunction(CheckBeginFunctionFunc checkfn);
   void _registerForEndFunction(CheckEndFunctionFunc checkfn);
 
   void _registerForBranchCondition(CheckBranchConditionFunc checkfn);

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp?rev=337215=337214=337215=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp Mon Jul 16 
13:47:45 2018
@@ -126,7 +126,7 @@ public:
  const CallEvent *Call,
  PointerEscapeKind Kind) const;
   void checkPreStmt(const ReturnStmt *RS, CheckerContext ) const;
-  void checkEndFunction(CheckerContext ) const;
+  void checkEndFunction(const ReturnStmt *RS, CheckerContext ) const;
 
 private:
   void diagnoseMissingReleases(CheckerContext ) const;
@@ -398,7 +398,7 @@ void ObjCDeallocChecker::checkPostObjCMe
 /// Check for missing releases even when -dealloc does not call
 /// '[super dealloc]'.
 void ObjCDeallocChecker::checkEndFunction(
-CheckerContext ) const {
+const ReturnStmt *RS, CheckerContext ) const {
   diagnoseMissingReleases(C);
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp?rev=337215=337214=337215=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp Mon Jul 16 

r336835 - [analyzer] Track multiple raw pointer symbols in DanglingInternalBufferChecker.

2018-07-11 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Wed Jul 11 12:08:02 2018
New Revision: 336835

URL: http://llvm.org/viewvc/llvm-project?rev=336835=rev
Log:
[analyzer] Track multiple raw pointer symbols in DanglingInternalBufferChecker.

Previously, the checker only tracked one raw pointer symbol for each
container object. But member functions returning a pointer to the
object's inner buffer may be called on the object several times. These
pointer symbols are now collected in a set inside the program state map
and thus all of them is checked for use-after-free problems.

Differential Revision: https://reviews.llvm.org/D49057

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
cfe/trunk/test/Analysis/dangling-internal-buffer.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp?rev=336835=336834=336835=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp Wed 
Jul 11 12:08:02 2018
@@ -24,10 +24,23 @@
 using namespace clang;
 using namespace ento;
 
-// FIXME: member functions that return a pointer to the container's internal
-// buffer may be called on the object many times, so the object's memory
-// region should have a list of pointer symbols associated with it.
-REGISTER_MAP_WITH_PROGRAMSTATE(RawPtrMap, const MemRegion *, SymbolRef)
+using PtrSet = llvm::ImmutableSet;
+
+// Associate container objects with a set of raw pointer symbols.
+REGISTER_MAP_WITH_PROGRAMSTATE(RawPtrMap, const MemRegion *, PtrSet)
+
+// This is a trick to gain access to PtrSet's Factory.
+namespace clang {
+namespace ento {
+template<> struct ProgramStateTrait
+  : public ProgramStatePartialTrait {
+  static void *GDMIndex() {
+static int Index = 0;
+return 
+  }
+};
+} // end namespace ento
+} // end namespace clang
 
 namespace {
 
@@ -61,7 +74,7 @@ public:
 bool isSymbolTracked(ProgramStateRef State, SymbolRef Sym) {
   RawPtrMapTy Map = State->get();
   for (const auto Entry : Map) {
-if (Entry.second == Sym)
+if (Entry.second.contains(Sym))
   return true;
   }
   return false;
@@ -88,11 +101,11 @@ void DanglingInternalBufferChecker::chec
 return;
 
   SVal Obj = ICall->getCXXThisVal();
-  const auto *TypedR = dyn_cast_or_null(Obj.getAsRegion());
-  if (!TypedR)
+  const auto *ObjRegion = 
dyn_cast_or_null(Obj.getAsRegion());
+  if (!ObjRegion)
 return;
 
-  auto *TypeDecl = TypedR->getValueType()->getAsCXXRecordDecl();
+  auto *TypeDecl = ObjRegion->getValueType()->getAsCXXRecordDecl();
   if (TypeDecl->getName() != "basic_string")
 return;
 
@@ -100,20 +113,30 @@ void DanglingInternalBufferChecker::chec
 
   if (Call.isCalled(CStrFn) || Call.isCalled(DataFn)) {
 SVal RawPtr = Call.getReturnValue();
-if (!RawPtr.isUnknown()) {
-  State = State->set(TypedR, RawPtr.getAsSymbol());
+if (SymbolRef Sym = RawPtr.getAsSymbol(/*IncludeBaseRegions=*/true)) {
+  // Start tracking this raw pointer by adding it to the set of symbols
+  // associated with this container object in the program state map.
+  PtrSet::Factory  = State->getStateManager().get_context();
+  const PtrSet *SetPtr = State->get(ObjRegion);
+  PtrSet Set = SetPtr ? *SetPtr : F.getEmptySet();
+  assert(C.wasInlined || !Set.contains(Sym));
+  Set = F.add(Set, Sym);
+  State = State->set(ObjRegion, Set);
   C.addTransition(State);
 }
 return;
   }
 
   if (isa(ICall)) {
-if (State->contains(TypedR)) {
-  const SymbolRef *StrBufferPtr = State->get(TypedR);
-  // FIXME: What if Origin is null?
+if (const PtrSet *PS = State->get(ObjRegion)) {
+  // Mark all pointer symbols associated with the deleted object released.
   const Expr *Origin = Call.getOriginExpr();
-  State = allocation_state::markReleased(State, *StrBufferPtr, Origin);
-  State = State->remove(TypedR);
+  for (const auto Symbol : *PS) {
+// NOTE: `Origin` may be null, and will be stored so in the symbol's
+// `RefState` in MallocChecker's `RegionState` program state map.
+State = allocation_state::markReleased(State, Symbol, Origin);
+  }
+  State = State->remove(ObjRegion);
   C.addTransition(State);
   return;
 }
@@ -123,15 +146,24 @@ void DanglingInternalBufferChecker::chec
 void DanglingInternalBufferChecker::checkDeadSymbols(SymbolReaper ,
  CheckerContext ) const {
   ProgramStateRef State = C.getState();
+  PtrSet::Factory  = State->getStateManager().get_context();
   RawPtrMapTy RPM = State->get();
   for (const auto Entry : RPM) {
-if (!SymReaper.isLive(Entry.second))
-  State = 

r336497 - [analyzer] Add support for data() in DanglingInternalBufferChecker.

2018-07-07 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Sat Jul  7 13:29:24 2018
New Revision: 336497

URL: http://llvm.org/viewvc/llvm-project?rev=336497=rev
Log:
[analyzer] Add support for data() in DanglingInternalBufferChecker.

DanglingInternalBufferChecker now tracks use-after-free problems related
to the incorrect usage of std::basic_string::data().

Differential Revision: https://reviews.llvm.org/D48532

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
cfe/trunk/test/Analysis/dangling-internal-buffer.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp?rev=336497=336496=336497=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp Sat 
Jul  7 13:29:24 2018
@@ -24,15 +24,16 @@
 using namespace clang;
 using namespace ento;
 
-// FIXME: c_str() may be called on a string object many times, so it should
-// have a list of symbols associated with it.
+// FIXME: member functions that return a pointer to the container's internal
+// buffer may be called on the object many times, so the object's memory
+// region should have a list of pointer symbols associated with it.
 REGISTER_MAP_WITH_PROGRAMSTATE(RawPtrMap, const MemRegion *, SymbolRef)
 
 namespace {
 
 class DanglingInternalBufferChecker
 : public Checker {
-  CallDescription CStrFn;
+  CallDescription CStrFn, DataFn;
 
 public:
   class DanglingBufferBRVisitor : public BugReporterVisitor {
@@ -67,7 +68,7 @@ public:
 }
   };
 
-  DanglingInternalBufferChecker() : CStrFn("c_str") {}
+  DanglingInternalBufferChecker() : CStrFn("c_str"), DataFn("data") {}
 
   /// Record the connection between the symbol returned by c_str() and the
   /// corresponding string object region in the ProgramState. Mark the symbol
@@ -97,7 +98,7 @@ void DanglingInternalBufferChecker::chec
 
   ProgramStateRef State = C.getState();
 
-  if (Call.isCalled(CStrFn)) {
+  if (Call.isCalled(CStrFn) || Call.isCalled(DataFn)) {
 SVal RawPtr = Call.getReturnValue();
 if (!RawPtr.isUnknown()) {
   State = State->set(TypedR, RawPtr.getAsSymbol());

Modified: cfe/trunk/test/Analysis/dangling-internal-buffer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dangling-internal-buffer.cpp?rev=336497=336496=336497=diff
==
--- cfe/trunk/test/Analysis/dangling-internal-buffer.cpp (original)
+++ cfe/trunk/test/Analysis/dangling-internal-buffer.cpp Sat Jul  7 13:29:24 
2018
@@ -7,6 +7,8 @@ class basic_string {
 public:
   ~basic_string();
   const CharT *c_str() const;
+  const CharT *data() const;
+  CharT *data();
 };
 
 typedef basic_string string;
@@ -21,59 +23,92 @@ void consume(const wchar_t *) {}
 void consume(const char16_t *) {}
 void consume(const char32_t *) {}
 
-void deref_after_scope_char() {
+void deref_after_scope_char_cstr() {
   const char *c;
   {
 std::string s;
 c = s.c_str(); // expected-note {{Pointer to dangling buffer was obtained 
here}}
   } // expected-note {{Internal buffer is released because the object was 
destroyed}}
+  std::string s;
+  const char *c2 = s.c_str();
   consume(c); // expected-warning {{Use of memory after it is freed}}
   // expected-note@-1 {{Use of memory after it is freed}}
 }
 
-void deref_after_scope_char2() {
+void deref_after_scope_char_data() {
   const char *c;
   {
 std::string s;
-c = s.c_str(); // expected-note {{Pointer to dangling buffer was obtained 
here}}
+c = s.data(); // expected-note {{Pointer to dangling buffer was obtained 
here}}
   } // expected-note {{Internal buffer is released because the object was 
destroyed}}
   std::string s;
-  const char *c2 = s.c_str();
+  const 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}}
+}
+
+void deref_after_scope_char_data_non_const() {
+  char *c;
+  {
+std::string s;
+c = s.data(); // expected-note {{Pointer to dangling buffer was obtained 
here}}
+  } // expected-note {{Internal buffer is released because the object was 
destroyed}}
+  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}}
 }
 
-void deref_after_scope_wchar_t() {
+
+void deref_after_scope_wchar_t_cstr() {
   const wchar_t *w;
   {
 std::wstring ws;
 w = ws.c_str(); // expected-note {{Pointer to dangling buffer was obtained 
here}}
   } // expected-note {{Internal buffer is released because the object was 
destroyed}}
+  std::wstring ws;
+  const wchar_t *w2 = ws.c_str();
+  consume(w); // expected-warning {{Use of 

r336495 - [analyzer] Highlight c_str() call in DanglingInternalBufferChecker.

2018-07-07 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Sat Jul  7 12:27:18 2018
New Revision: 336495

URL: http://llvm.org/viewvc/llvm-project?rev=336495=rev
Log:
[analyzer] Highlight c_str() call in DanglingInternalBufferChecker.

Add a bug visitor to DanglingInternalBufferChecker that places a note
at the point where the dangling pointer was obtained. The visitor is
handed over to MallocChecker and attached to the report there.

Differential Revision: https://reviews.llvm.org/D48522

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

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h?rev=336495=336494=336495=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h Sat Jul  7 12:27:18 
2018
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_ALLOCATIONSTATE_H
 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_ALLOCATIONSTATE_H
 
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 
 namespace clang {
@@ -20,6 +21,11 @@ namespace allocation_state {
 ProgramStateRef markReleased(ProgramStateRef State, SymbolRef Sym,
  const Expr *Origin);
 
+/// This function provides an additional visitor that augments the bug report
+/// with information relevant to memory errors caused by the misuse of
+/// AF_InternalBuffer symbols.
+std::unique_ptr getDanglingBufferBRVisitor(SymbolRef Sym);
+
 } // end namespace allocation_state
 
 } // end namespace ento

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp?rev=336495=336494=336495=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp Sat 
Jul  7 12:27:18 2018
@@ -7,30 +7,66 @@
 //
 
//===--===//
 //
-// This file defines a check that marks a raw pointer to a C++ standard library
-// container's inner buffer released when the object is destroyed. This
-// information can be used by MallocChecker to detect use-after-free problems.
+// This file defines a check that marks a raw pointer to a C++ container's
+// inner buffer released when the object is destroyed. This information can
+// be used by MallocChecker to detect use-after-free problems.
 //
 
//===--===//
 
+#include "AllocationState.h"
 #include "ClangSACheckers.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "AllocationState.h"
 
 using namespace clang;
 using namespace ento;
 
+// FIXME: c_str() may be called on a string object many times, so it should
+// have a list of symbols associated with it.
+REGISTER_MAP_WITH_PROGRAMSTATE(RawPtrMap, const MemRegion *, SymbolRef)
+
 namespace {
 
-class DanglingInternalBufferChecker : public Checker {
+class DanglingInternalBufferChecker
+: public Checker {
   CallDescription CStrFn;
 
 public:
+  class DanglingBufferBRVisitor : public BugReporterVisitor {
+SymbolRef PtrToBuf;
+
+  public:
+DanglingBufferBRVisitor(SymbolRef Sym) : PtrToBuf(Sym) {}
+
+static void *getTag() {
+  static int Tag = 0;
+  return 
+}
+
+void Profile(llvm::FoldingSetNodeID ) const override {
+  ID.AddPointer(getTag());
+}
+
+std::shared_ptr VisitNode(const ExplodedNode *N,
+   const ExplodedNode *PrevN,
+   BugReporterContext ,
+   BugReport ) override;
+
+// FIXME: Scan the map once in the visitor's constructor and do a direct
+// lookup by region.
+bool isSymbolTracked(ProgramStateRef State, SymbolRef Sym) {
+  RawPtrMapTy Map = State->get();
+  for (const auto Entry : Map) {
+if (Entry.second == Sym)
+  return true;
+  }
+  return false;
+}
+  };
+
   DanglingInternalBufferChecker() : CStrFn("c_str") {}
 
   /// Record the connection between the symbol 

r336493 - [analyzer] Fix -Wcovered-switch-default warning in MallocChecker.

2018-07-07 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Sat Jul  7 11:37:37 2018
New Revision: 336493

URL: http://llvm.org/viewvc/llvm-project?rev=336493=rev
Log:
[analyzer] Fix -Wcovered-switch-default warning in MallocChecker.

Remove unnecessary default case that caused buildbot failures.

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=336493=336492=336493=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Sat Jul  7 11:37:37 
2018
@@ -2915,7 +2915,6 @@ std::shared_ptr Mal
   Msg = "Internal buffer is released because the object was destroyed";
   break;
 case AF_None:
-default:
   llvm_unreachable("Unhandled allocation family!");
   }
   StackHint = new StackHintGeneratorForSymbol(Sym,


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


r336489 - [analyzer] Highlight container object destruction in MallocChecker.

2018-07-07 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Sat Jul  7 10:22:45 2018
New Revision: 336489

URL: http://llvm.org/viewvc/llvm-project?rev=336489=rev
Log:
[analyzer] Highlight container object destruction in MallocChecker.

Extend MallocBugVisitor to place a note at the point where objects with
AF_InternalBuffer allocation family are destroyed.

Differential Revision: https://reviews.llvm.org/D48521

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/test/Analysis/dangling-internal-buffer.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=336489=336488=336489=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Sat Jul  7 10:22:45 
2018
@@ -480,8 +480,13 @@ private:
 inline bool isReleased(const RefState *S, const RefState *SPrev,
const Stmt *Stmt) {
   // Did not track -> released. Other state (allocated) -> released.
-  return (Stmt && (isa(Stmt) || isa(Stmt)) &&
-  (S && S->isReleased()) && (!SPrev || !SPrev->isReleased()));
+  // The statement associated with the release might be missing.
+  bool IsReleased = (S && S->isReleased()) &&
+(!SPrev || !SPrev->isReleased());
+  assert(!IsReleased ||
+ (Stmt && (isa(Stmt) || isa(Stmt))) ||
+ (!Stmt && S->getAllocationFamily() == AF_InternalBuffer));
+  return IsReleased;
 }
 
 inline bool isRelinquished(const RefState *S, const RefState *SPrev,
@@ -2850,8 +2855,17 @@ static bool isReferenceCountingPointerDe
 std::shared_ptr 
MallocChecker::MallocBugVisitor::VisitNode(
 const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext ,
 BugReport ) {
+
+  ProgramStateRef state = N->getState();
+  ProgramStateRef statePrev = PrevN->getState();
+
+  const RefState *RS = state->get(Sym);
+  const RefState *RSPrev = statePrev->get(Sym);
+
   const Stmt *S = PathDiagnosticLocation::getStmt(N);
-  if (!S)
+  // When dealing with containers, we sometimes want to give a note
+  // even if the statement is missing.
+  if (!S && (!RS || RS->getAllocationFamily() != AF_InternalBuffer))
 return nullptr;
 
   const LocationContext *CurrentLC = N->getLocationContext();
@@ -2876,14 +2890,6 @@ std::shared_ptr Mal
 }
   }
 
-  ProgramStateRef state = N->getState();
-  ProgramStateRef statePrev = PrevN->getState();
-
-  const RefState *RS = state->get(Sym);
-  const RefState *RSPrev = statePrev->get(Sym);
-  if (!RS)
-return nullptr;
-
   // FIXME: We will eventually need to handle non-statement-based events
   // (__attribute__((cleanup))).
 
@@ -2896,7 +2902,22 @@ std::shared_ptr Mal
   StackHint = new StackHintGeneratorForSymbol(Sym,
   "Returned allocated memory");
 } else if (isReleased(RS, RSPrev, S)) {
-  Msg = "Memory is released";
+  const auto Family = RS->getAllocationFamily();
+  switch(Family) {
+case AF_Alloca:
+case AF_Malloc:
+case AF_CXXNew:
+case AF_CXXNewArray:
+case AF_IfNameIndex:
+  Msg = "Memory is released";
+  break;
+case AF_InternalBuffer:
+  Msg = "Internal buffer is released because the object was destroyed";
+  break;
+case AF_None:
+default:
+  llvm_unreachable("Unhandled allocation family!");
+  }
   StackHint = new StackHintGeneratorForSymbol(Sym,
  "Returning; memory was released");
 
@@ -2967,8 +2988,19 @@ std::shared_ptr Mal
   assert(StackHint);
 
   // Generate the extra diagnostic.
-  PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
- N->getLocationContext());
+  PathDiagnosticLocation Pos;
+  if (!S) {
+assert(RS->getAllocationFamily() == AF_InternalBuffer);
+auto PostImplCall = N->getLocation().getAs();
+if (!PostImplCall)
+  return nullptr;
+Pos = PathDiagnosticLocation(PostImplCall->getLocation(),
+ BRC.getSourceManager());
+  } else {
+Pos = PathDiagnosticLocation(S, BRC.getSourceManager(),
+ N->getLocationContext());
+  }
+
   return std::make_shared(Pos, Msg, true, StackHint);
 }
 

Modified: cfe/trunk/test/Analysis/dangling-internal-buffer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dangling-internal-buffer.cpp?rev=336489=336488=336489=diff
==
--- cfe/trunk/test/Analysis/dangling-internal-buffer.cpp (original)
+++ cfe/trunk/test/Analysis/dangling-internal-buffer.cpp Sat Jul  7 10:22:45 
2018
@@ -26,7 +26,7 @@ void deref_after_scope_char() {
   {
 

r334352 - [analyzer] Clean up the program state map of DanglingInternalBufferChecker.

2018-06-11 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Sat Jun  9 14:08:27 2018
New Revision: 334352

URL: http://llvm.org/viewvc/llvm-project?rev=334352=rev
Log:
[analyzer] Clean up the program state map of DanglingInternalBufferChecker.

Symbols are cleaned up from the program state map when they go out of scope.
Memory regions are cleaned up when the corresponding object is destroyed, and
additionally in 'checkDeadSymbols' in case destructor modeling was incomplete.

Differential Revision: https://reviews.llvm.org/D47416

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp?rev=334352=334351=334352=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp Sat 
Jun  9 14:08:27 2018
@@ -26,7 +26,8 @@ using namespace ento;
 
 namespace {
 
-class DanglingInternalBufferChecker : public Checker {
+class DanglingInternalBufferChecker : public Checker {
   CallDescription CStrFn;
 
 public:
@@ -36,6 +37,9 @@ public:
   /// corresponding string object region in the ProgramState. Mark the symbol
   /// released if the string object is destroyed.
   void checkPostCall(const CallEvent , CheckerContext ) const;
+
+  /// Clean up the ProgramState map.
+  void checkDeadSymbols(SymbolReaper , CheckerContext ) const;
 };
 
 } // end anonymous namespace
@@ -76,12 +80,29 @@ void DanglingInternalBufferChecker::chec
   // FIXME: What if Origin is null?
   const Expr *Origin = Call.getOriginExpr();
   State = allocation_state::markReleased(State, *StrBufferPtr, Origin);
+  State = State->remove(TypedR);
   C.addTransition(State);
   return;
 }
   }
 }
 
+void DanglingInternalBufferChecker::checkDeadSymbols(SymbolReaper ,
+ CheckerContext ) const {
+  ProgramStateRef State = C.getState();
+  RawPtrMapTy RPM = State->get();
+  for (const auto Entry : RPM) {
+if (!SymReaper.isLive(Entry.second))
+  State = State->remove(Entry.first);
+if (!SymReaper.isLiveRegion(Entry.first)) {
+  // Due to incomplete destructor support, some dead regions might still
+  // remain in the program state map. Clean them up.
+  State = State->remove(Entry.first);
+}
+  }
+  C.addTransition(State);
+}
+
 void ento::registerDanglingInternalBufferChecker(CheckerManager ) {
   registerNewDeleteChecker(Mgr);
   Mgr.registerChecker();


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


r334348 - [analyzer] Add dangling internal buffer check.

2018-06-09 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Sat Jun  9 06:03:49 2018
New Revision: 334348

URL: http://llvm.org/viewvc/llvm-project?rev=334348=rev
Log:
[analyzer] Add dangling internal buffer check.

This check will mark raw pointers to C++ standard library container internal
buffers 'released' when the objects themselves are destroyed. Such information
can be used by MallocChecker to warn about use-after-free problems.

In this first version, 'std::basic_string's are supported.

Differential Revision: https://reviews.llvm.org/D47135

Added:
cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h
cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
cfe/trunk/test/Analysis/dangling-internal-buffer.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=334348=334347=334348=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Sat Jun  9 
06:03:49 2018
@@ -300,6 +300,11 @@ def VirtualCallChecker : Checker<"Virtua
 
 let ParentPackage = CplusplusAlpha in {
 
+def DanglingInternalBufferChecker : Checker<"DanglingInternalBuffer">,
+  HelpText<"Check for internal raw pointers of C++ standard library containers 
"
+   "used after deallocation">,
+  DescFile<"DanglingInternalBufferChecker.cpp">;
+
 def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
   HelpText<"Reports destructions of polymorphic objects with a non-virtual "
"destructor in their base class">,

Added: cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h?rev=334348=auto
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h (added)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h Sat Jun  9 06:03:49 
2018
@@ -0,0 +1,28 @@
+//===--- AllocationState.h - *- C++ 
-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_ALLOCATIONSTATE_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_ALLOCATIONSTATE_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+
+namespace clang {
+namespace ento {
+
+namespace allocation_state {
+
+ProgramStateRef markReleased(ProgramStateRef State, SymbolRef Sym,
+ const Expr *Origin);
+
+} // end namespace allocation_state
+
+} // end namespace ento
+} // end namespace clang
+
+#endif

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=334348=334347=334348=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Sat Jun  9 06:03:49 
2018
@@ -27,6 +27,7 @@ add_clang_library(clangStaticAnalyzerChe
   CloneChecker.cpp
   ConversionChecker.cpp
   CXXSelfAssignmentChecker.cpp
+  DanglingInternalBufferChecker.cpp
   DeadStoresChecker.cpp
   DebugCheckers.cpp
   DeleteWithNonVirtualDtorChecker.cpp

Added: cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp?rev=334348=auto
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp 
(added)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DanglingInternalBufferChecker.cpp Sat 
Jun  9 06:03:49 2018
@@ -0,0 +1,88 @@
+//=== DanglingInternalBufferChecker.cpp ---*- C++ 
-*--//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This file defines a check that marks a raw pointer to a C++ standard library
+// container's inner buffer released when the object is destroyed. This
+// information can be used by MallocChecker to detect use-after-free problems.
+//

r314061 - [docs] Fix typos in Clang's User's Manual.

2017-09-23 Thread Reka Kovacs via cfe-commits
Author: rkovacs
Date: Sat Sep 23 05:13:32 2017
New Revision: 314061

URL: http://llvm.org/viewvc/llvm-project?rev=314061=rev
Log:
[docs] Fix typos in Clang's User's Manual.

Modified:
cfe/trunk/docs/UsersManual.rst

Modified: cfe/trunk/docs/UsersManual.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=314061=314060=314061=diff
==
--- cfe/trunk/docs/UsersManual.rst (original)
+++ cfe/trunk/docs/UsersManual.rst Sat Sep 23 05:13:32 2017
@@ -107,7 +107,7 @@ Options to Control Error and Warning Mes
 
 .. option:: -Wno-error=foo
 
-  Turn warning "foo" into an warning even if :option:`-Werror` is specified.
+  Turn warning "foo" into a warning even if :option:`-Werror` is specified.
 
 .. option:: -Wfoo
 
@@ -677,7 +677,7 @@ Current limitations
 
 Other Options
 -
-Clang options that that don't fit neatly into other categories.
+Clang options that don't fit neatly into other categories.
 
 .. option:: -MV
 


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