summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Analysis/additive-folding-range-constraints.c158
-rw-r--r--clang/test/Analysis/additive-folding.cpp146
-rw-r--r--clang/test/Analysis/out-of-bounds.c6
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 ***
OpenPOWER on IntegriCloud