diff --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp --- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp @@ -249,8 +249,12 @@ } bool isStdOstreamOperatorCall(const CallEvent &Call) { - if (Call.getNumArgs() != 2 || - !Call.getDecl()->getDeclContext()->isStdNamespace()) + if (Call.getNumArgs() != 2) + return false; + const auto *Decl = Call.getDecl(); + if (!Decl) + return false; + if (!Decl->getDeclContext()->isStdNamespace()) return false; const auto *FC = dyn_cast(&Call); if (!FC) @@ -265,6 +269,18 @@ isStdBasicOstream(Call.getArgExpr(0)); } +static bool isPotentiallyComparisionOpCall(const CallEvent &Call) { + if (Call.getNumArgs() != 2) + return false; + const auto *Decl = Call.getDecl(); + if (!Decl) + return false; + if (!Decl->getDeclContext()->isStdNamespace()) + return false; + return smartptr::isStdSmartPtr(Call.getArgExpr(0)) || + smartptr::isStdSmartPtr(Call.getArgExpr(1)); +} + bool SmartPtrModeling::evalCall(const CallEvent &Call, CheckerContext &C) const { @@ -272,14 +288,11 @@ // 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)) {