t-8ch updated this revision to Diff 451117. t-8ch added a comment. - Inline tiny functions - Use structured binding - Rename findReferenceParameter -> findReferenceParameters
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D131067/new/ 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,35 @@ return i + j; } +//===----------------------------------------------------------------------===// +// Dead store checking involving reference parameters. +//===----------------------------------------------------------------------===// + +struct ReferenceParameter { + int *ptr; + + ReferenceParameter(int &i) : ptr(&i) {} + void function(int &i) { + ptr = &i; + } + + int value() { + return *ptr; + } +}; + +void referenceParameters() { + int i = 7; + ReferenceParameter r(i); + i = 8; + if (r.value() == 8) + ; + i = 9; // FIXME this is a false-negative + + int j = 10; + r.function(j); + j = 11; + if (r.value() == 11) + ; + j = 12; // FIXME this is a false-negative +} Index: clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -483,12 +483,22 @@ 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)) { + if (auto *FD = dyn_cast_or_null<FunctionDecl>(CE->getCalleeDecl())) + findReferenceParameters(FD, CE->arguments()); + return; + } + + if (auto *CE = dyn_cast<CXXConstructExpr>(S)) { + findReferenceParameters(CE->getConstructor(), CE->arguments()); + return; + } + const UnaryOperator *U = dyn_cast<UnaryOperator>(S); if (!U) return; @@ -522,6 +532,21 @@ Escaped.insert(cast<VarDecl>(VD)); } } + + void findReferenceParameters(const FunctionDecl *FD, + CallExpr::const_arg_range Args) { + for (const auto &[Param, Arg] : llvm::zip(FD->parameters(), Args)) { + if (!Param->getType()->isReferenceType()) + continue; + + auto *DRE = dyn_cast<DeclRefExpr>(Arg); + if (!DRE) + continue; + + if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) + Escaped.insert(VD); + } + } }; } // 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,35 @@ return i + j; } +//===----------------------------------------------------------------------===// +// Dead store checking involving reference parameters. +//===----------------------------------------------------------------------===// + +struct ReferenceParameter { + int *ptr; + + ReferenceParameter(int &i) : ptr(&i) {} + void function(int &i) { + ptr = &i; + } + + int value() { + return *ptr; + } +}; + +void referenceParameters() { + int i = 7; + ReferenceParameter r(i); + i = 8; + if (r.value() == 8) + ; + i = 9; // FIXME this is a false-negative + + int j = 10; + r.function(j); + j = 11; + if (r.value() == 11) + ; + j = 12; // FIXME this is a false-negative +} Index: clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -483,12 +483,22 @@ 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)) { + if (auto *FD = dyn_cast_or_null<FunctionDecl>(CE->getCalleeDecl())) + findReferenceParameters(FD, CE->arguments()); + return; + } + + if (auto *CE = dyn_cast<CXXConstructExpr>(S)) { + findReferenceParameters(CE->getConstructor(), CE->arguments()); + return; + } + const UnaryOperator *U = dyn_cast<UnaryOperator>(S); if (!U) return; @@ -522,6 +532,21 @@ Escaped.insert(cast<VarDecl>(VD)); } } + + void findReferenceParameters(const FunctionDecl *FD, + CallExpr::const_arg_range Args) { + for (const auto &[Param, Arg] : llvm::zip(FD->parameters(), Args)) { + if (!Param->getType()->isReferenceType()) + continue; + + auto *DRE = dyn_cast<DeclRefExpr>(Arg); + if (!DRE) + continue; + + if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) + Escaped.insert(VD); + } + } }; } // end anonymous namespace
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits