diff --git a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -483,12 +483,21 @@ void operator()(const Stmt *S) { // Check for '&'. Any VarDecl whose address has been taken we treat as // escaped. - // FIXME: What about references? if (auto *LE = dyn_cast(S)) { findLambdaReferenceCaptures(LE); return; } + if (auto *CE = dyn_cast(S)) { + findCallReferenceParameters(CE); + return; + } + + if (auto *CE = dyn_cast(S)) { + findConstructorReferenceParameters(CE); + return; + } + const UnaryOperator *U = dyn_cast(S); if (!U) return; @@ -522,6 +531,31 @@ Escaped.insert(VD); } } + + void findReferenceParameter(const FunctionDecl *FD, + CallExpr::const_arg_range Args) { + for (const auto It : llvm::zip(FD->parameters(), Args)) { + if (!std::get<0>(It)->getType()->isReferenceType()) + continue; + + auto *DRE = dyn_cast(std::get<1>(It)); + if (!DRE) + continue; + + if (auto *VD = dyn_cast(DRE->getDecl())) + Escaped.insert(VD); + } + } + + void findCallReferenceParameters(const CallExpr *CE) { + if (auto *FD = dyn_cast_or_null(CE->getCalleeDecl())) { + findReferenceParameter(FD, CE->arguments()); + } + } + + void findConstructorReferenceParameters(const CXXConstructExpr *CE) { + findReferenceParameter(CE->getConstructor(), CE->arguments()); + } }; } // end anonymous namespace diff --git a/clang/test/Analysis/dead-stores.cpp b/clang/test/Analysis/dead-stores.cpp --- a/clang/test/Analysis/dead-stores.cpp +++ b/clang/test/Analysis/dead-stores.cpp @@ -217,3 +217,22 @@ return i + j; } +//===----------------------------------------------------------------------===// +// Dead store checking involving references. +//===----------------------------------------------------------------------===// + +void functionReferenceParameter(int &i) {} + +struct constructorReferenceParameter { + constructorReferenceParameter(int &i) {} +}; + +void referenceParameters() { + int i = 5; + functionReferenceParameter(i); + i = 6; + + int j = 7; + constructorReferenceParameter k(j); + j = 8; +}