diff options
author | Jordy Rose <jediknil@belkadan.com> | 2012-05-08 03:27:16 +0000 |
---|---|---|
committer | Jordy Rose <jediknil@belkadan.com> | 2012-05-08 03:27:16 +0000 |
commit | 1d8db493f86761df9470254a2ad572fc6abf1bf6 (patch) | |
tree | 0154247883972fa4f0431ed121dc6fc66d7f1181 /test/Analysis/additive-folding-range-constraints.c | |
parent | d3b6d99cd57522b15dcec0eb771a97d9599d4db2 (diff) |
[analyzer] Rework both constraint managers to handle mixed-type comparisons.
This involves keeping track of three separate types: the symbol type, the
adjustment type, and the comparison type. For example, in "$x + 5 > 0ULL",
if the type of $x is 'signed char', the adjustment type is 'int' and the
comparison type is 'unsigned long long'. Most of the time these three types
will be the same, but we should still do the right thing when the
comparison value is out of range, and wraparound should be calculated in
the adjustment type.
This also re-disables an out-of-bounds test; we were extracting the symbol
from non-additive SymIntExprs, but then throwing away the integer.
Sorry for the large patch; both the basic and range constraint managers needed
to be updated together, since they share code in SimpleConstraintManager.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156361 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Analysis/additive-folding-range-constraints.c')
-rw-r--r-- | test/Analysis/additive-folding-range-constraints.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/test/Analysis/additive-folding-range-constraints.c b/test/Analysis/additive-folding-range-constraints.c index 056110f579..a64c9102fc 100644 --- a/test/Analysis/additive-folding-range-constraints.c +++ b/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 +} |