Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1458,11 +1458,16 @@ // If this is an assignment expression, we can track the value // being assigned. - if (Optional P = Succ->getLocationAs()) + if (Optional P = Succ->getLocationAs()) { if (const BinaryOperator *BO = P->getStmtAs()) if (BO->isAssignmentOp()) InitE = BO->getRHS(); + if (const CXXConstructExpr *CE = P->getStmtAs()) { + InitE = CE; + } + } + // If this is a call entry, the variable should be a parameter. // FIXME: Handle CXXThisRegion as well. (This is not a priority because // 'this' should never be NULL, but this visitor isn't just for NULL and @@ -2397,33 +2402,41 @@ ProgramStateRef RVState = RVNode->getState(); SVal V = RVState->getSValAsScalarOrLoc(E, RVNode->getLocationContext()); - const auto *BO = dyn_cast(E); - if (!BO || !BO->isMultiplicativeOp() || !V.isZeroConstant()) - return {}; - - SVal RHSV = RVState->getSVal(BO->getRHS(), RVNode->getLocationContext()); - SVal LHSV = RVState->getSVal(BO->getLHS(), RVNode->getLocationContext()); - - // Track both LHS and RHS of a multiplication. Tracker::Result CombinedResult; Tracker &Parent = getParentTracker(); - - const auto track = [&CombinedResult, &Parent, ExprNode, Opts](Expr *Inner) { + const auto track = [&CombinedResult, &Parent, ExprNode, + Opts](const Expr *Inner) { CombinedResult.combineWith(Parent.track(Inner, ExprNode, Opts)); }; - if (BO->getOpcode() == BO_Mul) { - if (LHSV.isZeroConstant()) - track(BO->getLHS()); - if (RHSV.isZeroConstant()) - track(BO->getRHS()); - } else { // Track only the LHS of a division or a modulo. - if (LHSV.isZeroConstant()) - track(BO->getLHS()); + const auto *BO = dyn_cast(E); + if (BO && BO->isMultiplicativeOp() && V.isZeroConstant()) { + SVal RHSV = RVState->getSVal(BO->getRHS(), RVNode->getLocationContext()); + SVal LHSV = RVState->getSVal(BO->getLHS(), RVNode->getLocationContext()); + + // Track both LHS and RHS of a multiplication. + if (BO->getOpcode() == BO_Mul) { + if (LHSV.isZeroConstant()) + track(BO->getLHS()); + if (RHSV.isZeroConstant()) + track(BO->getRHS()); + } else { // Track only the LHS of a division or a modulo. + if (LHSV.isZeroConstant()) + track(BO->getLHS()); + } + + return CombinedResult; } - return CombinedResult; + if (const auto *CE = dyn_cast(E)) { + for (auto &&arg : CE->arguments()) + track(arg); + + return CombinedResult; + } + + return {}; } }; Index: clang/test/Analysis/osobject-retain-release.cpp =================================================================== --- clang/test/Analysis/osobject-retain-release.cpp +++ clang/test/Analysis/osobject-retain-release.cpp @@ -693,6 +693,7 @@ void test_smart_ptr_leak() { OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an OSObject of type 'OSObject' with a +1 retain count}} + // expected-note@-1{{'obj' initialized here}} { OSObjectPtr p(obj); // expected-note{{Calling constructor for 'smart_ptr'}} // expected-note@-1{{Returning from constructor for 'smart_ptr'}}