diff options
author | Peter Szecsi <szepet95@gmail.com> | 2018-03-27 12:16:56 +0000 |
---|---|---|
committer | Peter Szecsi <szepet95@gmail.com> | 2018-03-27 12:16:56 +0000 |
commit | 4c87d233b07c6876dfd27a0ce7e727131f0023d7 (patch) | |
tree | ce2d0bd5d5f6ad00b0f8c2e957cd41fac358d31c | |
parent | fff11dbc4829bd1752bf5ee824317f38e2ae05b6 (diff) | |
download | bcm5719-llvm-4c87d233b07c6876dfd27a0ce7e727131f0023d7.tar.gz bcm5719-llvm-4c87d233b07c6876dfd27a0ce7e727131f0023d7.zip |
[analyzer] LoopUnrolling: update the matched assignment operators
Extended the matched assignment operators when checking for bound changes in a body of the loop by using the freshly added isAssignmentOperator matcher.
This covers all the (current) possible assignments, tests added as well.
Differential Revision: https://reviews.llvm.org/D38921
llvm-svn: 328619
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp | 4 | ||||
-rw-r--r-- | clang/test/Analysis/loop-unrolling.cpp | 110 |
2 files changed, 100 insertions, 14 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp b/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp index a8c4b05cea1..b32e9348841 100644 --- a/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp +++ b/clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp @@ -97,9 +97,7 @@ changeIntBoundNode(internal::Matcher<Decl> VarNodeMatcher) { unaryOperator(anyOf(hasOperatorName("--"), hasOperatorName("++")), hasUnaryOperand(ignoringParenImpCasts( declRefExpr(to(varDecl(VarNodeMatcher)))))), - binaryOperator(anyOf(hasOperatorName("="), hasOperatorName("+="), - hasOperatorName("/="), hasOperatorName("*="), - hasOperatorName("-=")), + binaryOperator(isAssignmentOperator(), hasLHS(ignoringParenImpCasts( declRefExpr(to(varDecl(VarNodeMatcher))))))); } diff --git a/clang/test/Analysis/loop-unrolling.cpp b/clang/test/Analysis/loop-unrolling.cpp index 1507accada5..aa145ac0af1 100644 --- a/clang/test/Analysis/loop-unrolling.cpp +++ b/clang/test/Analysis/loop-unrolling.cpp @@ -99,13 +99,101 @@ int simple_no_unroll5() { return 0; } +int no_unroll_assignment() { + for (int i = 0; i < 9; i++) { + i = i + 1; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment2() { + for (int i = 0; i < 9; i++) { + i *= 2; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment3() { + for (int i = 128; i > 0; i--) { + i /= 2; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment4() { + for (int i = 0; i < 9; i++) { + i -= 2; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment5() { + for (int i = 0; i < 9; i++) { + i += 1; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment6() { + for (int i = 128; i > 0; i--) { + i >>= 1; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment7() { + for (int i = 0; i < 512; i++) { + i <<= 1; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment8() { + for (int i = 0; i < 9; i++) { + i %= 8; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment9() { + for (int i = 0; i < 9; i++) { + i &= 31; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment10() { + for (int i = 0; i < 9; i++) { + i |= 2; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + +int no_unroll_assignment11() { + for (int i = 0; i < 9; i++) { + i ^= 2; + clang_analyzer_numTimesReached(); // expected-warning {{4}} + } + return 0; +} + int make_new_branches_loop_cached() { for (int i = 0; i < 8; i++) { clang_analyzer_numTimesReached(); // expected-warning {{4}} - if(getNum()){ - (void) i; // Since this Stmt does not change the State the analyzer - // won't make a new execution path but reuse the earlier nodes. - } + if (getNum()) { + (void)i; // Since this Stmt does not change the State the analyzer + // won't make a new execution path but reuse the earlier nodes. + } } clang_analyzer_warnIfReached(); // no-warning return 0; @@ -115,7 +203,7 @@ int make_new_branches_loop_uncached() { int l = 2; for (int i = 0; i < 8; i++) { clang_analyzer_numTimesReached(); // expected-warning {{10}} - if(getNum()){ + if (getNum()) { ++l; } } @@ -127,7 +215,7 @@ int make_new_branches_loop_uncached2() { int l = 2; for (int i = 0; i < 8; i++) { clang_analyzer_numTimesReached(); // expected-warning {{10}} - if(getNum()){ + if (getNum()) { ++l; } (void)&i; // This ensures that the loop won't be unrolled. @@ -185,7 +273,7 @@ int nested_outer_unrolled() { for (j = 0; j < 9; ++j) { clang_analyzer_numTimesReached(); // expected-warning {{4}} a[j] = 22; - (void) &j; // ensures that the inner loop won't be unrolled + (void)&j; // ensures that the inner loop won't be unrolled } a[i] = 42; } @@ -268,8 +356,8 @@ int recursion_unroll1(bool b) { int k = 2; for (int i = 0; i < 5; i++) { clang_analyzer_numTimesReached(); // expected-warning {{13}} - if(i == 0 && b) // Splits the state in the first iteration but the recursion - // call will be unrolled anyway since the condition is known there. + if (i == 0 && b) // Splits the state in the first iteration but the recursion + // call will be unrolled anyway since the condition is known there. recursion_unroll1(false); clang_analyzer_numTimesReached(); // expected-warning {{14}} } @@ -281,7 +369,7 @@ int recursion_unroll2(bool b) { int k = 0; for (int i = 0; i < 5; i++) { clang_analyzer_numTimesReached(); // expected-warning {{9}} - if(i == 0 && b) + if (i == 0 && b) recursion_unroll2(false); clang_analyzer_numTimesReached(); // expected-warning {{9}} } @@ -307,7 +395,7 @@ int recursion_unroll4(bool b) { int k = 2; for (int i = 0; i < 5; i++) { clang_analyzer_numTimesReached(); // expected-warning {{13}} - if(i == 0 && b) { + if (i == 0 && b) { recursion_unroll4(false); continue; } |