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 @@ -164,6 +164,11 @@ 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()) { // FIXME: getStmtForDiagnostics() does nasty things in order to provide // a valid statement for body farms, do we need this behavior here? @@ -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 @@ -499,3 +499,15 @@ clang_analyzer_numTimesReached(); // expected-warning {{6}} } } + +void parm_by_value_as_loop_counter(int i) { + for (i = 0; i < 10; ++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}} + } +}