diff --git a/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp b/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp --- a/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp +++ b/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp @@ -160,8 +160,13 @@ } static bool isPossiblyEscaped(const VarDecl *VD, ExplodedNode *N) { - // Global variables and parameters assumed as escaped variables. - if (VD->hasGlobalStorage() || VD->getKind() == Decl::ParmVar) + // Global variables assumed as escaped variables. + if (VD->hasGlobalStorage()) + return true; + + const bool isParm = VD->getKind() == Decl::ParmVar; + // Reference parameters are assumed as escaped variables. + if (isParm && VD->getType()->isReferenceType()) return true; while (!N->pred_empty()) { @@ -193,6 +198,11 @@ N = N->getFirstPred(); } + + // Parameter declaration will not be found. + if (isParm) + return false; + llvm_unreachable("Reached root without finding the declaration of VD"); } diff --git a/clang/test/Analysis/loop-unrolling.cpp b/clang/test/Analysis/loop-unrolling.cpp --- a/clang/test/Analysis/loop-unrolling.cpp +++ b/clang/test/Analysis/loop-unrolling.cpp @@ -500,8 +500,14 @@ } } -void arg_as_loop_counter(int i) { +void parm_by_value_as_loop_counter(int i) { for (i = 0; i < 10; ++i) { - (void)i; + clang_analyzer_numTimesReached(); // expected-warning {{10}} + } +} + +void parm_by_ref_as_loop_counter(int &i) { + for (i = 0; i < 10; ++i) { + clang_analyzer_numTimesReached(); // expected-warning {{4}} } }