t-8ch created this revision. Herald added subscribers: steakhal, manas, ASDenysPetrov, martong, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, baloghadamsoftware, xazax.hun. Herald added a reviewer: NoQ. Herald added a project: All. t-8ch requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D131067 Files: clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp clang/test/Analysis/dead-stores.cpp Index: clang/test/Analysis/dead-stores.cpp =================================================================== --- clang/test/Analysis/dead-stores.cpp +++ clang/test/Analysis/dead-stores.cpp @@ -217,3 +217,26 @@ return i + j; } +//===----------------------------------------------------------------------===// +// Dead store checking involving references. +//===----------------------------------------------------------------------===// + +void functionReferenceParameter(int &i) { + i = 5; // no warning +} + +struct constructorReferenceParameter { + constructorReferenceParameter(int &i) { + i = 5; // no warning + } +}; + +void referenceParameters() { + int i = 5; + functionReferenceParameter(i); + i = 6; + + int j = 7; + constructorReferenceParameter k(j); + j = 8; +} Index: clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ 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<LambdaExpr>(S)) { findLambdaReferenceCaptures(LE); return; } + if (auto *CE = dyn_cast<CallExpr>(S)) { + findCallReferenceParameters(CE); + return; + } + + if (auto *CE = dyn_cast<CXXConstructExpr>(S)) { + findConstructorReferenceParameters(CE); + return; + } + const UnaryOperator *U = dyn_cast<UnaryOperator>(S); if (!U) return; @@ -522,6 +531,33 @@ Escaped.insert(VD); } } + + void findReferenceParameter(const ParmVarDecl *Param, const Expr *Arg) { + if (Param->getType()->isReferenceType()) { + if (auto *DRE = dyn_cast<DeclRefExpr>(Arg)) { + if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { + Escaped.insert(VD); + } + } + } + } + + void findCallReferenceParameters(const CallExpr *CE) { + if (auto *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl())) { + unsigned numParams = FD->getNumParams(); + for (unsigned i = 0; i < numParams; ++i) { + findReferenceParameter(FD->getParamDecl(i), CE->getArg(i)); + } + } + } + + void findConstructorReferenceParameters(const CXXConstructExpr *CE) { + const FunctionDecl *FD = CE->getConstructor(); + unsigned numParams = FD->getNumParams(); + for (unsigned i = 0; i < numParams; ++i) { + findReferenceParameter(FD->getParamDecl(i), CE->getArg(i)); + } + } }; } // end anonymous namespace
Index: clang/test/Analysis/dead-stores.cpp =================================================================== --- clang/test/Analysis/dead-stores.cpp +++ clang/test/Analysis/dead-stores.cpp @@ -217,3 +217,26 @@ return i + j; } +//===----------------------------------------------------------------------===// +// Dead store checking involving references. +//===----------------------------------------------------------------------===// + +void functionReferenceParameter(int &i) { + i = 5; // no warning +} + +struct constructorReferenceParameter { + constructorReferenceParameter(int &i) { + i = 5; // no warning + } +}; + +void referenceParameters() { + int i = 5; + functionReferenceParameter(i); + i = 6; + + int j = 7; + constructorReferenceParameter k(j); + j = 8; +} Index: clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ 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<LambdaExpr>(S)) { findLambdaReferenceCaptures(LE); return; } + if (auto *CE = dyn_cast<CallExpr>(S)) { + findCallReferenceParameters(CE); + return; + } + + if (auto *CE = dyn_cast<CXXConstructExpr>(S)) { + findConstructorReferenceParameters(CE); + return; + } + const UnaryOperator *U = dyn_cast<UnaryOperator>(S); if (!U) return; @@ -522,6 +531,33 @@ Escaped.insert(VD); } } + + void findReferenceParameter(const ParmVarDecl *Param, const Expr *Arg) { + if (Param->getType()->isReferenceType()) { + if (auto *DRE = dyn_cast<DeclRefExpr>(Arg)) { + if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { + Escaped.insert(VD); + } + } + } + } + + void findCallReferenceParameters(const CallExpr *CE) { + if (auto *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl())) { + unsigned numParams = FD->getNumParams(); + for (unsigned i = 0; i < numParams; ++i) { + findReferenceParameter(FD->getParamDecl(i), CE->getArg(i)); + } + } + } + + void findConstructorReferenceParameters(const CXXConstructExpr *CE) { + const FunctionDecl *FD = CE->getConstructor(); + unsigned numParams = FD->getNumParams(); + for (unsigned i = 0; i < numParams; ++i) { + findReferenceParameter(FD->getParamDecl(i), CE->getArg(i)); + } + } }; } // end anonymous namespace
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits