diff options
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/Analysis/additive-folding-range-constraints.c | 158 | ||||
| -rw-r--r-- | clang/test/Analysis/additive-folding.cpp | 146 | ||||
| -rw-r--r-- | clang/test/Analysis/out-of-bounds.c | 6 |
3 files changed, 308 insertions, 2 deletions
diff --git a/clang/test/Analysis/additive-folding-range-constraints.c b/clang/test/Analysis/additive-folding-range-constraints.c index 056110f5790..a64c9102fcc 100644 --- a/clang/test/Analysis/additive-folding-range-constraints.c +++ b/clang/test/Analysis/additive-folding-range-constraints.c @@ -6,6 +6,9 @@ void *malloc(size_t); void free(void *); #define NULL ((void*)0) #define UINT_MAX (~0U) +#define INT_MAX (UINT_MAX & (UINT_MAX >> 1)) +#define INT_MIN (-INT_MAX - 1) + // Each of these adjusted ranges has an adjustment small enough to split the // solution range across an overflow boundary (Min for <, Max for >). @@ -97,3 +100,158 @@ void largeAdjustmentLE (unsigned a) { free(b); return; // no-warning } + + +// Test the nine cases in RangeConstraintManager's pinning logic. +void mixedComparisons1(signed char a) { + // Case 1: The range is entirely below the symbol's range. + int min = INT_MIN; + + if ((a - 2) < (min + 5LL)) + return; // expected-warning{{never executed}} + + if (a == 0) + return; // no-warning + if (a == 0x7F) + return; // no-warning + if (a == -0x80) + return; // no-warning + return; // no-warning +} + +void mixedComparisons2(signed char a) { + // Case 2: Only the lower end of the range is outside. + if ((a - 5) < (-0x81LL)) { + if (a == 0) + return; // expected-warning{{never executed}} + if (a == 0x7F) + return; // expected-warning{{never executed}} + if (a == -0x80) + return; // no-warning + return; // no-warning + } else { + return; // no-warning + } +} + +void mixedComparisons3(signed char a) { + // Case 3: The entire symbol range is covered. + if ((a - 0x200) < -0x100LL) { + if (a == 0) + return; // no-warning + if (a == 0x7F) + return; // no-warning + if (a == -0x80) + return; // no-warning + return; // no-warning + } else { + return; // expected-warning{{never executed}} + } +} + +void mixedComparisons4(signed char a) { + // Case 4: The range wraps around, but the lower wrap is out-of-range. + if ((a - 5) > 0LL) { + if (a == 0) + return; // expected-warning{{never executed}} + if (a == 0x7F) + return; // no-warning + if (a == -0x80) + return; // expected-warning{{never executed}} + return; // no-warning + } else { + return; // no-warning + } +} + +void mixedComparisons5(signed char a) { + // Case 5a: The range is inside and does not wrap. + if ((a + 5) == 0LL) { + if (a == 0) + return; // expected-warning{{never executed}} + if (a == 0x7F) + return; // expected-warning{{never executed}} + if (a == -0x80) + return; // expected-warning{{never executed}} + return; // no-warning + } else { + return; // no-warning + } +} + +void mixedComparisons5Wrap(signed char a) { + // Case 5b: The range is inside and does wrap. + if ((a + 5) != 0LL) { + if (a == 0) + return; // no-warning + if (a == 0x7F) + return; // no-warning + if (a == -0x80) + return; // no-warning + return; // no-warning + } else { + return; // no-warning + } +} + +void mixedComparisons6(signed char a) { + // Case 6: Only the upper end of the range is outside. + if ((a + 5) > 0x81LL) { + if (a == 0) + return; // expected-warning{{never executed}} + if (a == 0x7F) + return; // no-warning + if (a == -0x80) + return; // expected-warning{{never executed}} + return; // no-warning + } else { + return; // no-warning + } +} + +void mixedComparisons7(signed char a) { + // Case 7: The range wraps around but is entirely outside the symbol's range. + int min = INT_MIN; + + if ((a + 2) < (min + 5LL)) + return; // expected-warning{{never executed}} + + if (a == 0) + return; // no-warning + if (a == 0x7F) + return; // no-warning + if (a == -0x80) + return; // no-warning + return; // no-warning +} + +void mixedComparisons8(signed char a) { + // Case 8: The range wraps, but the upper wrap is out of range. + if ((a + 5) < 0LL) { + if (a == 0) + return; // expected-warning{{never executed}} + if (a == 0x7F) + return; // expected-warning{{never executed}} + if (a == -0x80) + return; // no-warning + return; // no-warning + } else { + return; // no-warning + } +} + +void mixedComparisons9(signed char a) { + // Case 9: The range is entirely above the symbol's range. + int max = INT_MAX; + + if ((a + 2) > (max - 5LL)) + return; // expected-warning{{never executed}} + + if (a == 0) + return; // no-warning + if (a == 0x7F) + return; // no-warning + if (a == -0x80) + return; // no-warning + return; // no-warning +} diff --git a/clang/test/Analysis/additive-folding.cpp b/clang/test/Analysis/additive-folding.cpp index 3c9bf3b2e6b..136dc08f164 100644 --- a/clang/test/Analysis/additive-folding.cpp +++ b/clang/test/Analysis/additive-folding.cpp @@ -7,6 +7,8 @@ void *malloc(size_t); void free(void *); #define NULL ((void*)0) #define UINT_MAX (~0U) +#define INT_MAX (UINT_MAX & (UINT_MAX >> 1)) +#define INT_MIN (-INT_MAX - 1) //--------------- // Plus/minus @@ -203,6 +205,140 @@ void tautologyLE (unsigned a) { } +// Tautologies from outside the range of the symbol +void tautologyOutsideGT(unsigned char a) { + void *b = malloc(1); + if (a > 0x100) + return; // expected-warning{{never executed}} + if (a > -1) + free(b); + return; // no-warning +} + +void tautologyOutsideGE(unsigned char a) { + void *b = malloc(1); + if (a >= 0x100) + return; // expected-warning{{never executed}} + if (a >= -1) + free(b); + return; // no-warning +} + +void tautologyOutsideLT(unsigned char a) { + void *b = malloc(1); + if (a < -1) + return; // expected-warning{{never executed}} + if (a < 0x100) + free(b); + return; // no-warning +} + +void tautologyOutsideLE (unsigned char a) { + void *b = malloc(1); + if (a <= -1) + return; // expected-warning{{never executed}} + if (a <= 0x100) + free(b); + return; // no-warning +} + +void tautologyOutsideEQ(unsigned char a) { + if (a == 0x100) + malloc(1); // expected-warning{{never executed}} + if (a == -1) + malloc(1); // expected-warning{{never executed}} +} + +void tautologyOutsideNE(unsigned char a) { + void *sentinel = malloc(1); + if (a != 0x100) + free(sentinel); + + sentinel = malloc(1); + if (a != -1) + free(sentinel); +} + + +// Wraparound with mixed types. Note that the analyzer assumes +// -fwrapv semantics. +void mixedWraparoundSanityCheck(int a) { + int max = INT_MAX; + int min = INT_MIN; + + int b = a + 1; + if (a == max && b != min) + return; // expected-warning{{never executed}} +} + +void mixedWraparoundGT(int a) { + int max = INT_MAX; + + if ((a + 2) > (max + 1LL)) + return; // expected-warning{{never executed}} +} + +void mixedWraparoundGE(int a) { + int max = INT_MAX; + int min = INT_MIN; + + if ((a + 2) >= (max + 1LL)) + return; // expected-warning{{never executed}} + + void *sentinel = malloc(1); + if ((a - 2LL) >= min) + free(sentinel); + return; // expected-warning{{leak}} +} + +void mixedWraparoundLT(int a) { + int min = INT_MIN; + + if ((a - 2) < (min - 1LL)) + return; // expected-warning{{never executed}} +} + +void mixedWraparoundLE(int a) { + int max = INT_MAX; + int min = INT_MIN; + + if ((a - 2) <= (min - 1LL)) + return; // expected-warning{{never executed}} + + void *sentinel = malloc(1); + if ((a + 2LL) <= max) + free(sentinel); + return; // expected-warning{{leak}} +} + +void mixedWraparoundEQ(int a) { + int max = INT_MAX; + + if ((a + 2) == (max + 1LL)) + return; // expected-warning{{never executed}} +} + +void mixedWraparoundNE(int a) { + int max = INT_MAX; + + void *sentinel = malloc(1); + if ((a + 2) != (max + 1LL)) + free(sentinel); + return; // no-warning +} + + +// Mixed-signedness comparisons. +void mixedSignedness(int a, unsigned b) { + int sMin = INT_MIN; + unsigned uMin = INT_MIN; + if (a == sMin && a != uMin) + return; // expected-warning{{never executed}} + if (b == uMin && b != sMin) + return; // expected-warning{{never executed}} +} + + // PR12206/12510 - When SimpleSValBuilder figures out that a symbol is fully // constrained, it should cast the value to the result type in a binary // operation...unless the binary operation is a comparison, in which case the @@ -268,3 +404,13 @@ void PR12206_truncation(signed char x) { if (value == (local + 1)) malloc(1); // expected-warning{{never executed}} } + +void multiplicativeSanityTest(int x) { + // At one point we were ignoring the *4 completely -- the constraint manager + // would see x < 8 and then declare the next part unreachable. + if (x*4 < 8) + return; + if (x == 3) + malloc(1); + return; // expected-warning{{leak}} +} diff --git a/clang/test/Analysis/out-of-bounds.c b/clang/test/Analysis/out-of-bounds.c index a97bba5bb3b..c1721703fb8 100644 --- a/clang/test/Analysis/out-of-bounds.c +++ b/clang/test/Analysis/out-of-bounds.c @@ -128,11 +128,13 @@ void test2_multi_ok(int x) { buf[0][0] = 1; // no-warning } -// Testing if solver handles (symbol * constant) < constant +// *** FIXME *** +// We don't get a warning here yet because our symbolic constraint solving +// doesn't handle: (symbol * constant) < constant void test3(int x) { int buf[100]; if (x < 0) - buf[x] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}} + buf[x] = 1; } // *** FIXME *** |

