summaryrefslogtreecommitdiff
path: root/clang/test/Analysis/additive-folding.c
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/Analysis/additive-folding.c')
-rw-r--r--clang/test/Analysis/additive-folding.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/clang/test/Analysis/additive-folding.c b/clang/test/Analysis/additive-folding.c
new file mode 100644
index 0000000..beb08aa
--- /dev/null
+++ b/clang/test/Analysis/additive-folding.c
@@ -0,0 +1,203 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,unix.Malloc -verify -analyzer-constraints=basic %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,unix.Malloc -verify -analyzer-constraints=range %s
+
+// These are used to trigger warnings.
+typedef typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+#define NULL ((void*)0)
+#define UINT_MAX -1U
+
+//---------------
+// Plus/minus
+//---------------
+
+void separateExpressions (int a) {
+ int b = a + 1;
+ --b;
+
+ char* buf = malloc(1);
+ if (a != 0 && b == 0)
+ return; // expected-warning{{never executed}}
+ free(buf);
+}
+
+void oneLongExpression (int a) {
+ // Expression canonicalization should still allow this to work, even though
+ // the first term is on the left.
+ int b = 15 + a + 15 - 10 - 20;
+
+ char* buf = malloc(1);
+ if (a != 0 && b == 0)
+ return; // expected-warning{{never executed}}
+ free(buf);
+}
+
+void mixedTypes (int a) {
+ char* buf = malloc(1);
+
+ // Different additive types should not cause crashes when constant-folding.
+ // This is part of PR7406.
+ int b = a + 1LL;
+ if (a != 0 && (b-1) == 0) // not crash
+ return; // expected-warning{{never executed}}
+
+ int c = a + 1U;
+ if (a != 0 && (c-1) == 0) // not crash
+ return; // expected-warning{{never executed}}
+
+ free(buf);
+}
+
+//---------------
+// Comparisons
+//---------------
+
+// Equality and inequality only
+void eq_ne (unsigned a) {
+ char* b = NULL;
+ if (a == UINT_MAX)
+ b = malloc(1);
+ if (a+1 != 0)
+ return; // no-warning
+ if (a-1 != UINT_MAX-1)
+ return; // no-warning
+ free(b);
+}
+
+void ne_eq (unsigned a) {
+ char* b = NULL;
+ if (a != UINT_MAX)
+ b = malloc(1);
+ if (a+1 == 0)
+ return; // no-warning
+ if (a-1 == UINT_MAX-1)
+ return; // no-warning
+ free(b);
+}
+
+// Mixed typed inequalities (part of PR7406)
+// These should not crash.
+void mixed_eq_ne (int a) {
+ char* b = NULL;
+ if (a == 1)
+ b = malloc(1);
+ if (a+1U != 2)
+ return; // no-warning
+ if (a-1U != 0)
+ return; // expected-warning{{never executed}}
+ free(b);
+}
+
+void mixed_ne_eq (int a) {
+ char* b = NULL;
+ if (a != 1)
+ b = malloc(1);
+ if (a+1U == 2)
+ return; // no-warning
+ if (a-1U == 0)
+ return; // expected-warning{{never executed}}
+ free(b);
+}
+
+
+// Simple order comparisons with no adjustment
+void baselineGT (unsigned a) {
+ char* b = NULL;
+ if (a > 0)
+ b = malloc(1);
+ if (a == 0)
+ return; // no-warning
+ free(b);
+}
+
+void baselineGE (unsigned a) {
+ char* b = NULL;
+ if (a >= UINT_MAX)
+ b = malloc(1);
+ if (a == UINT_MAX)
+ free(b);
+ return; // no-warning
+}
+
+void baselineLT (unsigned a) {
+ char* b = NULL;
+ if (a < UINT_MAX)
+ b = malloc(1);
+ if (a == UINT_MAX)
+ return; // no-warning
+ free(b);
+}
+
+void baselineLE (unsigned a) {
+ char* b = NULL;
+ if (a <= 0)
+ b = malloc(1);
+ if (a == 0)
+ free(b);
+ return; // no-warning
+}
+
+
+// Adjustment gives each of these an extra solution!
+void adjustedGT (unsigned a) {
+ char* b = NULL;
+ if (a-1 > UINT_MAX-1)
+ b = malloc(1);
+ return; // expected-warning{{leak}}
+}
+
+void adjustedGE (unsigned a) {
+ char* b = NULL;
+ if (a-1 >= UINT_MAX-1)
+ b = malloc(1);
+ if (a == UINT_MAX)
+ free(b);
+ return; // expected-warning{{leak}}
+}
+
+void adjustedLT (unsigned a) {
+ char* b = NULL;
+ if (a+1 < 1)
+ b = malloc(1);
+ return; // expected-warning{{leak}}
+}
+
+void adjustedLE (unsigned a) {
+ char* b = NULL;
+ if (a+1 <= 1)
+ b = malloc(1);
+ if (a == 0)
+ free(b);
+ return; // expected-warning{{leak}}
+}
+
+
+// Tautologies
+void tautologyGT (unsigned a) {
+ char* b = malloc(1);
+ if (a > UINT_MAX)
+ return; // no-warning
+ free(b);
+}
+
+void tautologyGE (unsigned a) {
+ char* b = malloc(1);
+ if (a >= 0) // expected-warning{{always true}}
+ free(b);
+ return; // no-warning
+}
+
+void tautologyLT (unsigned a) {
+ char* b = malloc(1);
+ if (a < 0) // expected-warning{{always false}}
+ return; // expected-warning{{never executed}}
+ free(b);
+}
+
+void tautologyLE (unsigned a) {
+ char* b = malloc(1);
+ if (a <= UINT_MAX)
+ free(b);
+ return; // no-warning
+}