@@ -163,9 +163,21 @@ void FactsGenerator::VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE) {
163163 }
164164}
165165
166+ static bool isStdMove (const FunctionDecl *FD) {
167+ return FD && FD->isInStdNamespace () && FD->getIdentifier () &&
168+ FD->getName () == " move" ;
169+ }
170+
166171void FactsGenerator::VisitCallExpr (const CallExpr *CE) {
167172 handleFunctionCall (CE, CE->getDirectCallee (),
168173 {CE->getArgs (), CE->getNumArgs ()});
174+ // Remember accessPath which moved using std::move.
175+ // TODO: If there is need, this could flow-sensitive
176+ if (isStdMove (CE->getDirectCallee ()))
177+ if (CE->getNumArgs () == 1 )
178+ if (auto *DRE =
179+ dyn_cast<DeclRefExpr>(CE->getArg (0 )->IgnoreParenImpCasts ()))
180+ MovedDecls.insert (DRE->getDecl ());
169181}
170182
171183void FactsGenerator::VisitCXXNullPtrLiteralExpr (
@@ -341,6 +353,8 @@ void FactsGenerator::handleLifetimeEnds(const CFGLifetimeEnds &LifetimeEnds) {
341353 // Iterate through all loans to see if any expire.
342354 for (const auto &Loan : FactMgr.getLoanMgr ().getLoans ()) {
343355 const AccessPath &LoanPath = Loan.Path ;
356+ if (MovedDecls.contains (LoanPath.D ))
357+ continue ;
344358 // Check if the loan is for a stack variable and if that variable
345359 // is the one being destructed.
346360 if (LoanPath.D == LifetimeEndsVD)
0 commit comments