[clang] 5dee501 - [analyzer] Move docs of SmartPtr to correct subcategory

2021-09-20 Thread Deep Majumder via cfe-commits

Author: Deep Majumder
Date: 2021-09-20T20:13:04+05:30
New Revision: 5dee50111c13bbc4480401e2eaa67f6bca1b480a

URL: 
https://github.com/llvm/llvm-project/commit/5dee50111c13bbc4480401e2eaa67f6bca1b480a
DIFF: 
https://github.com/llvm/llvm-project/commit/5dee50111c13bbc4480401e2eaa67f6bca1b480a.diff

LOG: [analyzer] Move docs of SmartPtr to correct subcategory

The docs of alpha.cplusplus.SmartPtr was incorrectly placed under
alpha.deadcode. Moved it to under alpha.cplusplus

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

Added: 


Modified: 
clang/docs/analyzer/checkers.rst

Removed: 




diff  --git a/clang/docs/analyzer/checkers.rst 
b/clang/docs/analyzer/checkers.rst
index 858c8e1303e8..89190b54e5a5 100644
--- a/clang/docs/analyzer/checkers.rst
+++ b/clang/docs/analyzer/checkers.rst
@@ -1838,6 +1838,20 @@ Method calls on a moved-from object and copying a 
moved-from object will be repo
a.foo();// warn: method call on a 'moved-from' object 'a'
  }
 
+.. _alpha-cplusplus-SmartPtr:
+
+alpha.cplusplus.SmartPtr (C++)
+""
+Check for dereference of null smart pointers.
+
+.. code-block:: cpp
+
+ void deref_smart_ptr() {
+   std::unique_ptr P;
+   *P; // warn: dereference of a default constructed smart unique_ptr
+ }
+
+
 alpha.deadcode
 ^^
 .. _alpha-deadcode-UnreachableCode:
@@ -1872,19 +1886,6 @@ Check unreachable code.
[x retain]; // warn
  }
 
-.. _alpha-cplusplus-SmartPtr:
-
-alpha.cplusplus.SmartPtr (C++)
-""
-Check for dereference of null smart pointers.
-
-.. code-block:: cpp
-
- void deref_smart_ptr() {
-   std::unique_ptr P;
-   *P; // warn: dereference of a default constructed smart unique_ptr
- }
-
 alpha.fuchsia
 ^
 



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


[clang] 198e677 - [analyzer] Add option to SATest.py for extra checkers

2021-08-16 Thread Deep Majumder via cfe-commits

Author: Deep Majumder
Date: 2021-08-17T10:42:57+05:30
New Revision: 198e6771e24fb5d8d9f3b155445ecc2a4f211004

URL: 
https://github.com/llvm/llvm-project/commit/198e6771e24fb5d8d9f3b155445ecc2a4f211004
DIFF: 
https://github.com/llvm/llvm-project/commit/198e6771e24fb5d8d9f3b155445ecc2a4f211004.diff

LOG: [analyzer] Add option to SATest.py for extra checkers

This patch adds the flag `extra-checkers` to the sub-command `build` for
passing a comma separated list of additional checkers to include.

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

Added: 


Modified: 
clang/utils/analyzer/SATest.py
clang/utils/analyzer/SATestBuild.py

Removed: 




diff  --git a/clang/utils/analyzer/SATest.py b/clang/utils/analyzer/SATest.py
index 176fe40a2b171..9931870b3b0dd 100755
--- a/clang/utils/analyzer/SATest.py
+++ b/clang/utils/analyzer/SATest.py
@@ -42,6 +42,7 @@ def build(parser, args):
   projects,
   args.override_compiler,
   args.extra_analyzer_config,
+  args.extra_checkers,
   args.regenerate,
   args.strictness)
 tests_passed = tester.test_all()
@@ -250,6 +251,10 @@ def main():
   dest="extra_analyzer_config", type=str,
   default="",
   help="Arguments passed to to -analyzer-config")
+build_parser.add_argument("--extra-checkers",
+  dest="extra_checkers", type=str,
+  default="",
+  help="Extra checkers to enable")
 build_parser.add_argument("--projects", action="store", default="",
   help="Comma-separated list of projects to test")
 build_parser.add_argument("--max-size", action="store", default=None,

diff  --git a/clang/utils/analyzer/SATestBuild.py 
b/clang/utils/analyzer/SATestBuild.py
index ed5c7379bb5b4..1977a8fc2aeff 100644
--- a/clang/utils/analyzer/SATestBuild.py
+++ b/clang/utils/analyzer/SATestBuild.py
@@ -213,6 +213,7 @@ class TestInfo(NamedTuple):
 project: ProjectInfo
 override_compiler: bool = False
 extra_analyzer_config: str = ""
+extra_checkers: str = ""
 is_reference_build: bool = False
 strictness: int = 0
 
@@ -233,13 +234,16 @@ class RegressionTester:
 """
 A component aggregating all of the project testing.
 """
+
 def __init__(self, jobs: int, projects: List[ProjectInfo],
  override_compiler: bool, extra_analyzer_config: str,
+ extra_checkers: str,
  regenerate: bool, strictness: bool):
 self.jobs = jobs
 self.projects = projects
 self.override_compiler = override_compiler
 self.extra_analyzer_config = extra_analyzer_config
+self.extra_checkers = extra_checkers
 self.regenerate = regenerate
 self.strictness = strictness
 
@@ -252,6 +256,7 @@ def test_all(self) -> bool:
 TestInfo(project,
  self.override_compiler,
  self.extra_analyzer_config,
+ self.extra_checkers,
  self.regenerate, self.strictness))
 if self.jobs <= 1:
 return self._single_threaded_test_all(projects_to_test)
@@ -305,10 +310,12 @@ class ProjectTester:
 """
 A component aggregating testing for one project.
 """
+
 def __init__(self, test_info: TestInfo, silent: bool = False):
 self.project = test_info.project
 self.override_compiler = test_info.override_compiler
 self.extra_analyzer_config = test_info.extra_analyzer_config
+self.extra_checkers = test_info.extra_checkers
 self.is_reference_build = test_info.is_reference_build
 self.strictness = test_info.strictness
 self.silent = silent
@@ -414,6 +421,8 @@ def scan_build(self, directory: str, output_dir: str,
 if 'SA_ADDITIONAL_CHECKERS' in os.environ:
 all_checkers = (all_checkers + ',' +
 os.environ['SA_ADDITIONAL_CHECKERS'])
+if self.extra_checkers != "":
+all_checkers += "," + self.extra_checkers
 
 # Run scan-build from within the patched source directory.
 cwd = os.path.join(directory, PATCHED_SOURCE_DIR_NAME)



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


[clang] 80068ca - [analyzer] Fix for faulty namespace test in SmartPtrModelling

2021-07-21 Thread Deep Majumder via cfe-commits

Author: Deep Majumder
Date: 2021-07-21T18:23:35+05:30
New Revision: 80068ca6232b32e3ab79eb2ed72fd73558179ad5

URL: 
https://github.com/llvm/llvm-project/commit/80068ca6232b32e3ab79eb2ed72fd73558179ad5
DIFF: 
https://github.com/llvm/llvm-project/commit/80068ca6232b32e3ab79eb2ed72fd73558179ad5.diff

LOG: [analyzer] Fix for faulty namespace test in SmartPtrModelling

This patch:
- Fixes how the std-namespace test is written in SmartPtrModelling
(now accounts for functions with no Decl available)
- Adds the smart pointer checker flag check where it was missing

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

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
clang/test/Analysis/smart-ptr.cpp

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp 
b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
index 253606b97ec6..09e885e8133f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -248,9 +248,12 @@ bool isStdBasicOstream(const Expr *E) {
   return hasStdClassWithName(RD, BASIC_OSTREAM_NAMES);
 }
 
+static bool isStdFunctionCall(const CallEvent &Call) {
+  return Call.getDecl() && Call.getDecl()->getDeclContext()->isStdNamespace();
+}
+
 bool isStdOstreamOperatorCall(const CallEvent &Call) {
-  if (Call.getNumArgs() != 2 ||
-  !Call.getDecl()->getDeclContext()->isStdNamespace())
+  if (Call.getNumArgs() != 2 || !isStdFunctionCall(Call))
 return false;
   const auto *FC = dyn_cast(&Call);
   if (!FC)
@@ -265,6 +268,13 @@ bool isStdOstreamOperatorCall(const CallEvent &Call) {
  isStdBasicOstream(Call.getArgExpr(0));
 }
 
+static bool isPotentiallyComparisionOpCall(const CallEvent &Call) {
+  if (Call.getNumArgs() != 2 || !isStdFunctionCall(Call))
+return false;
+  return smartptr::isStdSmartPtr(Call.getArgExpr(0)) ||
+ smartptr::isStdSmartPtr(Call.getArgExpr(1));
+}
+
 bool SmartPtrModeling::evalCall(const CallEvent &Call,
 CheckerContext &C) const {
 
@@ -272,14 +282,11 @@ bool SmartPtrModeling::evalCall(const CallEvent &Call,
 
   // If any one of the arg is a unique_ptr, then
   // we can try this function
-  if (Call.getNumArgs() == 2 &&
-  Call.getDecl()->getDeclContext()->isStdNamespace())
-if (smartptr::isStdSmartPtr(Call.getArgExpr(0)) ||
-smartptr::isStdSmartPtr(Call.getArgExpr(1)))
-  if (handleComparisionOp(Call, C))
-return true;
-
-  if (isStdOstreamOperatorCall(Call))
+  if (ModelSmartPtrDereference && isPotentiallyComparisionOpCall(Call))
+if (handleComparisionOp(Call, C))
+  return true;
+
+  if (ModelSmartPtrDereference && isStdOstreamOperatorCall(Call))
 return handleOstreamOperator(Call, C);
 
   if (Call.isCalled(StdSwapCall)) {

diff  --git a/clang/test/Analysis/smart-ptr.cpp 
b/clang/test/Analysis/smart-ptr.cpp
index 37d5eed1217b..d3046d69ca83 100644
--- a/clang/test/Analysis/smart-ptr.cpp
+++ b/clang/test/Analysis/smart-ptr.cpp
@@ -536,3 +536,10 @@ void 
testOstreamDoesntInvalidateGlobals(std::unique_ptr P) {
 }
 
 #endif
+
+// The following test isn't really a "smart-ptr" test
+// It came up during a bug fix (D106296)
+void testCheckForFunctionsWithNoDecl(void (*bar)(bool, bool)) {
+  // This should NOT crash.
+  bar(true, false);
+}



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


[clang] d825309 - [analyzer] Handle std::make_unique

2021-07-18 Thread Deep Majumder via cfe-commits

Author: Deep Majumder
Date: 2021-07-18T19:54:28+05:30
New Revision: d825309352b4c5c01da7c935e49994f8f257

URL: 
https://github.com/llvm/llvm-project/commit/d825309352b4c5c01da7c935e49994f8f257
DIFF: 
https://github.com/llvm/llvm-project/commit/d825309352b4c5c01da7c935e49994f8f257.diff

LOG: [analyzer] Handle std::make_unique

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

Added: 


Modified: 
clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
clang/test/Analysis/Inputs/system-header-simulator-cxx.h
clang/test/Analysis/smart-ptr-text-output.cpp

Removed: 




diff  --git 
a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index 64c61a3514be..87a49cf4ffe9 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -238,6 +238,14 @@ class SValBuilder {
 const LocationContext *LCtx,
 unsigned Count);
 
+  /// Conjure a symbol representing heap allocated memory region.
+  ///
+  /// Note, now, the expression *doesn't* need to represent a location.
+  /// But the type need to!
+  DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E,
+const LocationContext *LCtx,
+QualType type, unsigned Count);
+
   DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(
   SymbolRef parentSymbol, const TypedValueRegion *region);
 

diff  --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp 
b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
index 2793980de1b6..253606b97ec6 100644
--- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -38,6 +38,7 @@ using namespace clang;
 using namespace ento;
 
 namespace {
+
 class SmartPtrModeling
 : public Checker {
@@ -88,6 +89,9 @@ class SmartPtrModeling
   {{"swap", 1}, &SmartPtrModeling::handleSwapMethod},
   {{"get"}, &SmartPtrModeling::handleGet}};
   const CallDescription StdSwapCall{{"std", "swap"}, 2};
+  const CallDescription StdMakeUniqueCall{{"std", "make_unique"}};
+  const CallDescription StdMakeUniqueForOverwriteCall{
+  {"std", "make_unique_for_overwrite"}};
 };
 } // end of anonymous namespace
 
@@ -187,12 +191,27 @@ static QualType getInnerPointerType(CheckerContext C, 
const CXXRecordDecl *RD) {
 return {};
 
   auto TemplateArgs = TSD->getTemplateArgs().asArray();
-  if (TemplateArgs.size() == 0)
+  if (TemplateArgs.empty())
 return {};
   auto InnerValueType = TemplateArgs[0].getAsType();
   return C.getASTContext().getPointerType(InnerValueType.getCanonicalType());
 }
 
+// This is for use with standalone-functions like std::make_unique,
+// std::make_unique_for_overwrite, etc. It reads the template parameter and
+// returns the pointer type corresponding to it,
+static QualType getPointerTypeFromTemplateArg(const CallEvent &Call,
+  CheckerContext &C) {
+  const auto *FD = dyn_cast_or_null(Call.getDecl());
+  if (!FD || !FD->isFunctionTemplateSpecialization())
+return {};
+  const auto &TemplateArgs = FD->getTemplateSpecializationArgs()->asArray();
+  if (TemplateArgs.size() == 0)
+return {};
+  auto ValueType = TemplateArgs[0].getAsType();
+  return C.getASTContext().getPointerType(ValueType.getCanonicalType());
+}
+
 // Helper method to get the inner pointer type of specialized smart pointer
 // Returns empty type if not found valid inner pointer type.
 static QualType getInnerPointerType(const CallEvent &Call, CheckerContext &C) {
@@ -248,6 +267,7 @@ bool isStdOstreamOperatorCall(const CallEvent &Call) {
 
 bool SmartPtrModeling::evalCall(const CallEvent &Call,
 CheckerContext &C) const {
+
   ProgramStateRef State = C.getState();
 
   // If any one of the arg is a unique_ptr, then
@@ -271,6 +291,50 @@ bool SmartPtrModeling::evalCall(const CallEvent &Call,
 return handleSwap(State, Call.getArgSVal(0), Call.getArgSVal(1), C);
   }
 
+  if (Call.isCalled(StdMakeUniqueCall) ||
+  Call.isCalled(StdMakeUniqueForOverwriteCall)) {
+if (!ModelSmartPtrDereference)
+  return false;
+
+const Optional ThisRegionOpt = 
Call.getReturnValueUnderConstruction();
+if (!ThisRegionOpt)
+  return false;
+
+const auto PtrVal = C.getSValBuilder().getConjuredHeapSymbolVal(
+Call.getOriginExpr(), C.getLocationContext(),
+getPointerTypeFromTemplateArg(Call, C), C.blockCount());
+
+const MemRegion *ThisRegion = ThisRegion

[clang] 0cd98be - [analyzer] Handle std::swap for std::unique_ptr

2021-07-18 Thread Deep Majumder via cfe-commits

Author: Deep Majumder
Date: 2021-07-18T14:38:55+05:30
New Revision: 0cd98bef1b6feec067a4c60df4df4d44a842811d

URL: 
https://github.com/llvm/llvm-project/commit/0cd98bef1b6feec067a4c60df4df4d44a842811d
DIFF: 
https://github.com/llvm/llvm-project/commit/0cd98bef1b6feec067a4c60df4df4d44a842811d.diff

LOG: [analyzer] Handle std::swap for std::unique_ptr

This patch handles the `std::swap` function specialization
for `std::unique_ptr`. Implemented to be very similar to
how `swap` method is handled

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

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/SmartPtr.h
clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
clang/lib/StaticAnalyzer/Core/BugReporter.cpp
clang/test/Analysis/smart-ptr-text-output.cpp

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h 
b/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h
index b4352b450c7fa..6a40f8eda5fa8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h
+++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h
@@ -25,6 +25,8 @@ bool isStdSmartPtrCall(const CallEvent &Call);
 bool isStdSmartPtr(const CXXRecordDecl *RD);
 bool isStdSmartPtr(const Expr *E);
 
+bool isStdSmartPtr(const CXXRecordDecl *RD);
+
 /// Returns whether the smart pointer is null or not.
 bool isNullSmartPtr(const ProgramStateRef State, const MemRegion *ThisRegion);
 

diff  --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp 
b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
index b56c969ca5a43..2793980de1b60 100644
--- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -63,7 +63,7 @@ class SmartPtrModeling
 private:
   void handleReset(const CallEvent &Call, CheckerContext &C) const;
   void handleRelease(const CallEvent &Call, CheckerContext &C) const;
-  void handleSwap(const CallEvent &Call, CheckerContext &C) const;
+  void handleSwapMethod(const CallEvent &Call, CheckerContext &C) const;
   void handleGet(const CallEvent &Call, CheckerContext &C) const;
   bool handleAssignOp(const CallEvent &Call, CheckerContext &C) const;
   bool handleMoveCtr(const CallEvent &Call, CheckerContext &C,
@@ -73,6 +73,8 @@ class SmartPtrModeling
   void handleBoolConversion(const CallEvent &Call, CheckerContext &C) const;
   bool handleComparisionOp(const CallEvent &Call, CheckerContext &C) const;
   bool handleOstreamOperator(const CallEvent &Call, CheckerContext &C) const;
+  bool handleSwap(ProgramStateRef State, SVal First, SVal Second,
+  CheckerContext &C) const;
   std::pair
   retrieveOrConjureInnerPtrVal(ProgramStateRef State,
const MemRegion *ThisRegion, const Expr *E,
@@ -83,8 +85,9 @@ class SmartPtrModeling
   CallDescriptionMap SmartPtrMethodHandlers{
   {{"reset"}, &SmartPtrModeling::handleReset},
   {{"release"}, &SmartPtrModeling::handleRelease},
-  {{"swap", 1}, &SmartPtrModeling::handleSwap},
+  {{"swap", 1}, &SmartPtrModeling::handleSwapMethod},
   {{"get"}, &SmartPtrModeling::handleGet}};
+  const CallDescription StdSwapCall{{"std", "swap"}, 2};
 };
 } // end of anonymous namespace
 
@@ -259,6 +262,15 @@ bool SmartPtrModeling::evalCall(const CallEvent &Call,
   if (isStdOstreamOperatorCall(Call))
 return handleOstreamOperator(Call, C);
 
+  if (Call.isCalled(StdSwapCall)) {
+// Check the first arg, if it is of std::unique_ptr type.
+assert(Call.getNumArgs() == 2 && "std::swap should have two arguments");
+const Expr *FirstArg = Call.getArgExpr(0);
+if (!smartptr::isStdSmartPtr(FirstArg->getType()->getAsCXXRecordDecl()))
+  return false;
+return handleSwap(State, Call.getArgSVal(0), Call.getArgSVal(1), C);
+  }
+
   if (!smartptr::isStdSmartPtrCall(Call))
 return false;
 
@@ -578,43 +590,52 @@ void SmartPtrModeling::handleRelease(const CallEvent 
&Call,
   // pointer.
 }
 
-void SmartPtrModeling::handleSwap(const CallEvent &Call,
-  CheckerContext &C) const {
+void SmartPtrModeling::handleSwapMethod(const CallEvent &Call,
+CheckerContext &C) const {
   // To model unique_ptr::swap() method.
   const auto *IC = dyn_cast(&Call);
   if (!IC)
 return;
 
-  const MemRegion *ThisRegion = IC->getCXXThisVal().getAsRegion();
-  if (!ThisRegion)
-return;
+  auto State = C.getState();
+  handleSwap(State, IC->getCXXThisVal(), Call.getArgSVal(0), C);
+}
 
-  const auto *ArgRegion = Call.getArgSVal(0).getAsRegion();
-  if (!ArgRegion)
-return;
+bool SmartPtrModeling::handleSwap(ProgramStateRef State, SVal First,
+  SVal Second, CheckerContext &C) const {
+  const MemRegion *FirstThisRegion = First.getAsRegion();
+  if (!FirstThisRegion)
+return false;
+  const MemRegion *SecondThisRegion = Second.getAsRegion();
+  if (!SecondThi

[clang] 4868825 - [analyzer] Model comparision methods of std::unique_ptr

2021-07-15 Thread Deep Majumder via cfe-commits

Author: Deep Majumder
Date: 2021-07-16T09:54:05+05:30
New Revision: 48688257c52dfc2c666b64730f0467c2cc38210c

URL: 
https://github.com/llvm/llvm-project/commit/48688257c52dfc2c666b64730f0467c2cc38210c
DIFF: 
https://github.com/llvm/llvm-project/commit/48688257c52dfc2c666b64730f0467c2cc38210c.diff

LOG: [analyzer] Model comparision methods of std::unique_ptr

This patch handles all the comparision methods (defined via overloaded
operators) on std::unique_ptr. These operators compare the underlying
pointers, which is modelled by comparing the corresponding inner-pointer
SVal. There is also a special case for comparing the same pointer.

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

Added: 


Modified: 
clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
clang/lib/StaticAnalyzer/Checkers/SmartPtr.h
clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp
clang/test/Analysis/Inputs/system-header-simulator-cxx.h
clang/test/Analysis/smart-ptr.cpp

Removed: 




diff  --git 
a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
index f253c14cc4870..a81d67ab30639 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h
@@ -13,7 +13,9 @@
 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERHELPERS_H
 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERHELPERS_H
 
+#include "clang/AST/OperationKinds.h"
 #include "clang/AST/Stmt.h"
+#include "clang/Basic/OperatorKinds.h"
 #include "llvm/ADT/Optional.h"
 #include 
 
@@ -69,6 +71,45 @@ Nullability getNullabilityAnnotation(QualType Type);
 /// token for an integer. If we cannot parse the value then None is returned.
 llvm::Optional tryExpandAsInteger(StringRef Macro, const Preprocessor 
&PP);
 
+class OperatorKind {
+  union {
+BinaryOperatorKind Bin;
+UnaryOperatorKind Un;
+  } Op;
+  bool IsBinary;
+
+public:
+  explicit OperatorKind(BinaryOperatorKind Bin) : Op{Bin}, IsBinary{true} {}
+  explicit OperatorKind(UnaryOperatorKind Un) : IsBinary{false} { Op.Un = Un; }
+  bool IsBinaryOp() const { return IsBinary; }
+
+  BinaryOperatorKind GetBinaryOpUnsafe() const {
+assert(IsBinary && "cannot get binary operator - we have a unary 
operator");
+return Op.Bin;
+  }
+
+  Optional GetBinaryOp() const {
+if (IsBinary)
+  return Op.Bin;
+return {};
+  }
+
+  UnaryOperatorKind GetUnaryOpUnsafe() const {
+assert(!IsBinary &&
+   "cannot get unary operator - we have a binary operator");
+return Op.Un;
+  }
+
+  Optional GetUnaryOp() const {
+if (!IsBinary)
+  return Op.Un;
+return {};
+  }
+};
+
+OperatorKind operationKindFromOverloadedOperator(OverloadedOperatorKind OOK,
+ bool IsBinary);
+
 } // namespace ento
 
 } // namespace clang

diff  --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h 
b/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h
index 92c386bbb2b09..b4352b450c7fa 100644
--- a/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h
+++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtr.h
@@ -22,6 +22,8 @@ namespace smartptr {
 
 /// Returns true if the event call is on smart pointer.
 bool isStdSmartPtrCall(const CallEvent &Call);
+bool isStdSmartPtr(const CXXRecordDecl *RD);
+bool isStdSmartPtr(const Expr *E);
 
 /// Returns whether the smart pointer is null or not.
 bool isNullSmartPtr(const ProgramStateRef State, const MemRegion *ThisRegion);

diff  --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp 
b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
index 6ee7bd9252b33..cfc61e89a40d2 100644
--- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
@@ -25,10 +25,13 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/ErrorHandling.h"
 #include 
 
 using namespace clang;
@@ -68,6 +71,11 @@ class SmartPtrModeling
   bool updateMovedSmartPointers(CheckerContext &C, const MemRegion *ThisRegion,
 const MemRegion *OtherSmartPtrRegion) const;
   void handleBoolConversion(const CallEvent &Call, CheckerContext &C) const;
+  bool handleComparisionOp(const CallEvent &Call, C