diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index 14b6049d717..bb9f2f79013 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -1028,4 +1028,75 @@ void test_negate_signed(int s) { if(10 < s && s < 20) { range(-s); // $ range=<=-11 range=>=-19 } -} \ No newline at end of file +} + +// By setting the guard after the use in another guard we +// don't get the useful information +void test_guard_after_use(int pos, int size, int offset) { + if (pos + offset >= size) { // $ overflow=+- + return; + } + if (offset != 1) { + return; + } + range(pos + 1); // $ overflow=+ range="==InitializeParameter: pos+1" MISSING: range="<=InitializeParameter: size-1" +} + +int cond(); + + +// This is basically what we get when we have a loop that calls +// realloc in some iterations +void alloc_in_loop(int origLen) { + if (origLen <= 10) { + return; + } + int len = origLen; + int index = 0; + while (cond()) { + if (index == len) { + if (len >= 1000) { + return; + } + len = len * 2; // $ overflow=- + } + // We want that index < len + range(index); // $ MISSING: range="<=InitializeParameter: len-1" + index++; + } +} + +// This came from a case where it handled the leftovers before an unrolled loop +void mask_at_start(int len) { + if (len < 0) { + return; + } + int leftOver = len & 63; + for (int i = 0; i < leftOver; i++) { + range(i); // $ range=<=62 range=>=0 range="<=Store: ... & ... | Store: leftOver-1" range="<=InitializeParameter: len-1" + } + // Do something with leftOver + for (int index = leftOver; index < len; index+=64) { + range(index); // $ range="<=InitializeParameter: len-1" + // This should be in bounds + range(index + 16); // $ range="<=InitializeParameter: len+15" range="==Phi: index+16" MISSING: range="<=InitializeParameter: len-1" + } +} + + +// Same as above but with modulo +void mod_at_start(int len) { + if (len < 0) { + return; + } + int leftOver = len % 64; + for (int i = 0; i < leftOver; i++) { + range(i); // $ range=<=62 range=>=0 range="<=Store: ... % ... | Store: leftOver-1" range="<=InitializeParameter: len-1" + } + // Do something with leftOver + for (int index = leftOver; index < len; index+=64) { + range(index); // $ range="<=InitializeParameter: len-1" + // This should be in bounds + range(index + 16); // $ range="<=InitializeParameter: len+15" range="==Phi: index+16" MISSING: range="<=InitializeParameter: len-49" + } +}