aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/Analysis/additive-folding-range-constraints.c227
-rw-r--r--test/Analysis/additive-folding.cpp324
-rw-r--r--test/Analysis/array-struct-region.c37
-rw-r--r--test/Analysis/base-init.cpp9
-rw-r--r--test/Analysis/bstring.c79
-rw-r--r--test/Analysis/constant-folding.c87
-rw-r--r--test/Analysis/initializer.cpp9
-rw-r--r--test/Analysis/method-call.cpp28
-rw-r--r--test/Analysis/ptr-arith.c217
-rw-r--r--test/Analysis/string-fail.c40
-rw-r--r--test/Analysis/string.c383
11 files changed, 472 insertions, 968 deletions
diff --git a/test/Analysis/additive-folding-range-constraints.c b/test/Analysis/additive-folding-range-constraints.c
index a64c9102fc..7eb55ab1e1 100644
--- a/test/Analysis/additive-folding-range-constraints.c
+++ b/test/Analysis/additive-folding-range-constraints.c
@@ -1,10 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,unix.Malloc -verify -analyzer-constraints=range %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range %s
+
+void clang_analyzer_eval(int);
-// 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 (~0U)
#define INT_MAX (UINT_MAX & (UINT_MAX >> 1))
#define INT_MIN (-INT_MAX - 1)
@@ -14,43 +11,27 @@ void free(void *);
// solution range across an overflow boundary (Min for <, Max for >).
// This corresponds to one set of branches in RangeConstraintManager.
void smallAdjustmentGT (unsigned a) {
- void *b = NULL;
if (a+2 > 1)
- b = malloc(1);
- if (a == UINT_MAX-1 || a == UINT_MAX)
- return; // no-warning
- else if (a < UINT_MAX-1)
- free(b);
- return; // no-warning
+ clang_analyzer_eval(a < UINT_MAX-1); // expected-warning{{TRUE}}
+ else
+ clang_analyzer_eval(a == UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
}
void smallAdjustmentGE (unsigned a) {
- void *b = NULL;
if (a+2 >= 1)
- b = malloc(1);
- if (a == UINT_MAX-1)
- return; // no-warning
- else if (a < UINT_MAX-1 || a == UINT_MAX)
- free(b);
- return; // no-warning
+ clang_analyzer_eval(a < UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
+ else
+ clang_analyzer_eval(a == UINT_MAX-1); // expected-warning{{TRUE}}
}
void smallAdjustmentLT (unsigned a) {
- void *b = NULL;
if (a+1 < 2)
- b = malloc(1);
- if (a == 0 || a == UINT_MAX)
- free(b);
- return; // no-warning
+ clang_analyzer_eval(a == 0 || a == UINT_MAX); // expected-warning{{TRUE}}
}
void smallAdjustmentLE (unsigned a) {
- void *b = NULL;
if (a+1 <= 2)
- b = malloc(1);
- if (a == 0 || a == 1 || a == UINT_MAX)
- free(b);
- return; // no-warning
+ clang_analyzer_eval(a == 0 || a == 1 || a == UINT_MAX); // expected-warning{{TRUE}}
}
@@ -58,154 +39,102 @@ void smallAdjustmentLE (unsigned a) {
// comparison value over an overflow boundary (Min for <, Max for >).
// This corresponds to one set of branches in RangeConstraintManager.
void largeAdjustmentGT (unsigned a) {
- void *b = NULL;
if (a-2 > UINT_MAX-1)
- b = malloc(1);
- if (a == 1 || a == 0)
- free(b);
- else if (a > 1)
- free(b);
- return; // no-warning
+ clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
+ else
+ clang_analyzer_eval(a != 1); // expected-warning{{TRUE}}
}
void largeAdjustmentGE (unsigned a) {
- void *b = NULL;
if (a-2 >= UINT_MAX-1)
- b = malloc(1);
- if (a > 1)
- return; // no-warning
- else if (a == 1 || a == 0)
- free(b);
- return; // no-warning
+ clang_analyzer_eval(a == 1 || a == 0); // expected-warning{{TRUE}}
+ else
+ clang_analyzer_eval(a > 1); // expected-warning{{TRUE}}
}
void largeAdjustmentLT (unsigned a) {
- void *b = NULL;
if (a+2 < 1)
- b = malloc(1);
- if (a == UINT_MAX-1 || a == UINT_MAX)
- free(b);
- else if (a < UINT_MAX-1)
- return; // no-warning
- return; // no-warning
+ clang_analyzer_eval(a == UINT_MAX-1); // expected-warning{{TRUE}}
+ else
+ clang_analyzer_eval(a != UINT_MAX-1); // expected-warning{{TRUE}}
}
void largeAdjustmentLE (unsigned a) {
- void *b = NULL;
if (a+2 <= 1)
- b = malloc(1);
- if (a < UINT_MAX-1)
- return; // no-warning
- else if (a == UINT_MAX-1 || a == UINT_MAX)
- free(b);
- return; // no-warning
+ clang_analyzer_eval(a == UINT_MAX-1 || a == UINT_MAX); // expected-warning{{TRUE}}
+ else
+ clang_analyzer_eval(a < UINT_MAX-1); // expected-warning{{TRUE}}
}
// Test the nine cases in RangeConstraintManager's pinning logic.
+// For out-of-range tautologies, it may be the negation that actually
+// triggers the case in question.
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}}
+ clang_analyzer_eval((a - 2) >= (min + 5LL)); // expected-warning{{TRUE}}
- if (a == 0)
- return; // no-warning
- if (a == 0x7F)
- return; // no-warning
- if (a == -0x80)
- return; // no-warning
- return; // no-warning
+ clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
}
void mixedComparisons2(signed char a) {
// Case 2: Only the lower end of the range is outside.
+ clang_analyzer_eval((a - 5) < (-0x81LL)); // expected-warning{{UNKNOWN}}
+
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
+ clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
}
}
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}}
- }
+ clang_analyzer_eval((a - 0x200) < -0x100LL); // expected-warning{{TRUE}}
+
+ clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
}
void mixedComparisons4(signed char a) {
// Case 4: The range wraps around, but the lower wrap is out-of-range.
+ clang_analyzer_eval((a - 5) > 0LL); // expected-warning{{UNKNOWN}}
+
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
+ clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
}
}
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
- }
-}
+ // Case 5: The range is inside and may or may not wrap.
+ clang_analyzer_eval((a + 5) == 0LL); // expected-warning{{UNKNOWN}}
-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
+ if ((a + 5) == 0LL) {
+ clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
} else {
- return; // no-warning
+ clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
}
}
void mixedComparisons6(signed char a) {
// Case 6: Only the upper end of the range is outside.
+ clang_analyzer_eval((a + 5) > 0x81LL); // expected-warning{{UNKNOWN}}
+
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
+ clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == -0x80); // expected-warning{{FALSE}}
}
}
@@ -213,30 +142,21 @@ 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}}
+ clang_analyzer_eval((a + 2) >= (min + 5LL)); // expected-warning{{TRUE}}
- if (a == 0)
- return; // no-warning
- if (a == 0x7F)
- return; // no-warning
- if (a == -0x80)
- return; // no-warning
- return; // no-warning
+ clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
}
void mixedComparisons8(signed char a) {
// Case 8: The range wraps, but the upper wrap is out of range.
+ clang_analyzer_eval((a + 5) < 0LL); // expected-warning{{UNKNOWN}}
+
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
+ clang_analyzer_eval(a == 0); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a == 0x7F); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
}
}
@@ -244,14 +164,9 @@ 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}}
+ clang_analyzer_eval((a + 2) <= (max - 5LL)); // expected-warning{{TRUE}}
- if (a == 0)
- return; // no-warning
- if (a == 0x7F)
- return; // no-warning
- if (a == -0x80)
- return; // no-warning
- return; // no-warning
+ clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == 0x7F); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a == -0x80); // expected-warning{{UNKNOWN}}
}
diff --git a/test/Analysis/additive-folding.cpp b/test/Analysis/additive-folding.cpp
index 136dc08f16..8c132fb4a9 100644
--- a/test/Analysis/additive-folding.cpp
+++ b/test/Analysis/additive-folding.cpp
@@ -1,11 +1,8 @@
-// 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)
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=basic -Wno-tautological-compare %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range -Wno-tautological-compare %s
+
+void clang_analyzer_eval(bool);
+
#define UINT_MAX (~0U)
#define INT_MAX (UINT_MAX & (UINT_MAX >> 1))
#define INT_MIN (-INT_MAX - 1)
@@ -18,10 +15,7 @@ void separateExpressions (int a) {
int b = a + 1;
--b;
- void *buf = malloc(1);
- if (a != 0 && b == 0)
- return; // expected-warning{{never executed}}
- free(buf);
+ clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}
}
void oneLongExpression (int a) {
@@ -29,26 +23,17 @@ void oneLongExpression (int a) {
// the first term is on the left.
int b = 15 + a + 15 - 10 - 20;
- void *buf = malloc(1);
- if (a != 0 && b == 0)
- return; // expected-warning{{never executed}}
- free(buf);
+ clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}}
}
void mixedTypes (int a) {
- void *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}}
+ clang_analyzer_eval(a != 0 && (b-1) == 0); // not crash, expected-warning{{FALSE}}
int c = a + 1U;
- if (a != 0 && (c-1) == 0) // not crash
- return; // expected-warning{{never executed}}
-
- free(buf);
+ clang_analyzer_eval(a != 0 && (c-1) == 0); // not crash, expected-warning{{FALSE}}
}
//---------------
@@ -57,206 +42,101 @@ void mixedTypes (int a) {
// Equality and inequality only
void eq_ne (unsigned a) {
- void *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) {
- void *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);
+ if (a == UINT_MAX) {
+ clang_analyzer_eval(a+1 == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a-1 == UINT_MAX-1); // expected-warning{{TRUE}}
+ } else {
+ clang_analyzer_eval(a+1 != 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a-1 != UINT_MAX-1); // expected-warning{{TRUE}}
+ }
}
// Mixed typed inequalities (part of PR7406)
// These should not crash.
void mixed_eq_ne (int a) {
- void *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) {
- void *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);
+ if (a == 1) {
+ clang_analyzer_eval(a+1U == 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a-1U == 0); // expected-warning{{TRUE}}
+ } else {
+ clang_analyzer_eval(a+1U != 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a-1U != 0); // expected-warning{{TRUE}}
+ }
}
// Simple order comparisons with no adjustment
void baselineGT (unsigned a) {
- void *b = NULL;
if (a > 0)
- b = malloc(1);
- if (a == 0)
- return; // no-warning
- free(b);
+ clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}
+ else
+ clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}
}
void baselineGE (unsigned a) {
- void *b = NULL;
if (a >= UINT_MAX)
- b = malloc(1);
- if (a == UINT_MAX)
- free(b);
- return; // no-warning
+ clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
+ else
+ clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}
}
void baselineLT (unsigned a) {
- void *b = NULL;
if (a < UINT_MAX)
- b = malloc(1);
- if (a == UINT_MAX)
- return; // no-warning
- free(b);
+ clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}}
+ else
+ clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}}
}
void baselineLE (unsigned a) {
- void *b = NULL;
if (a <= 0)
- b = malloc(1);
- if (a == 0)
- free(b);
- return; // no-warning
+ clang_analyzer_eval(a == 0); // expected-warning{{TRUE}}
+ else
+ clang_analyzer_eval(a != 0); // expected-warning{{TRUE}}
}
// Adjustment gives each of these an extra solution!
void adjustedGT (unsigned a) {
- void *b = NULL;
- if (a-1 > UINT_MAX-1)
- b = malloc(1);
- return; // expected-warning{{leak}}
+ clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}
}
void adjustedGE (unsigned a) {
- void *b = NULL;
+ clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}}
+
if (a-1 >= UINT_MAX-1)
- b = malloc(1);
- if (a == UINT_MAX)
- free(b);
- return; // expected-warning{{leak}}
+ clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}}
}
void adjustedLT (unsigned a) {
- void *b = NULL;
- if (a+1 < 1)
- b = malloc(1);
- return; // expected-warning{{leak}}
+ clang_analyzer_eval(a+1 < 1); // expected-warning{{UNKNOWN}}
}
void adjustedLE (unsigned a) {
- void *b = NULL;
+ clang_analyzer_eval(a+1 <= 1); // expected-warning{{UNKNOWN}}
+
if (a+1 <= 1)
- b = malloc(1);
- if (a == 0)
- free(b);
- return; // expected-warning{{leak}}
+ clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}}
}
// Tautologies
-void tautologyGT (unsigned a) {
- void *b = malloc(1);
- if (a > UINT_MAX)
- return; // no-warning
- free(b);
-}
-
-void tautologyGE (unsigned a) {
- void *b = malloc(1);
- if (a >= 0) // expected-warning{{always true}}
- free(b);
- return; // no-warning
-}
-
-void tautologyLT (unsigned a) {
- void *b = malloc(1);
- if (a < 0) // expected-warning{{always false}}
- return; // expected-warning{{never executed}}
- free(b);
-}
-
-void tautologyLE (unsigned a) {
- void *b = malloc(1);
- if (a <= UINT_MAX)
- free(b);
- return; // no-warning
+// The negative forms are exercised as well
+// because clang_analyzer_eval tests both possibilities.
+void tautologies(unsigned a) {
+ clang_analyzer_eval(a <= UINT_MAX); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a >= 0); // expected-warning{{TRUE}}
}
// 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 tautologiesOutside(unsigned char a) {
+ clang_analyzer_eval(a <= 0x100); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a < 0x100); // expected-warning{{TRUE}}
-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
-}
+ clang_analyzer_eval(a != 0x100); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a != -1); // expected-warning{{TRUE}}
-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);
+ clang_analyzer_eval(a > -1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a >= -1); // expected-warning{{TRUE}}
}
@@ -267,64 +147,32 @@ void mixedWraparoundSanityCheck(int a) {
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}}
+ clang_analyzer_eval(a == max && b != min); // expected-warning{{FALSE}}
}
-void mixedWraparoundGE(int a) {
+void mixedWraparoundLE_GT(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}}
+ clang_analyzer_eval((a + 2) <= (max + 1LL)); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a - 2) > (min - 1LL)); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a + 2LL) <= max); // expected-warning{{UNKNOWN}}
}
-void mixedWraparoundLE(int a) {
+void mixedWraparoundGE_LT(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}}
+ clang_analyzer_eval((a + 2) < (max + 1LL)); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a - 2) >= (min - 1LL)); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a - 2LL) >= min); // expected-warning{{UNKNOWN}}
}
-void mixedWraparoundNE(int a) {
+void mixedWraparoundEQ_NE(int a) {
int max = INT_MAX;
- void *sentinel = malloc(1);
- if ((a + 2) != (max + 1LL))
- free(sentinel);
- return; // no-warning
+ clang_analyzer_eval((a + 2) != (max + 1LL)); // expected-warning{{TRUE}}
+ clang_analyzer_eval((a + 2LL) == (max + 1LL)); // expected-warning{{UNKNOWN}}
}
@@ -332,10 +180,9 @@ void mixedWraparoundNE(int a) {
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}}
+
+ clang_analyzer_eval(a == sMin && a != uMin); // expected-warning{{FALSE}}
+ clang_analyzer_eval(b == uMin && b != sMin); // expected-warning{{FALSE}}
}
@@ -365,16 +212,12 @@ void PR12206(int x) {
// turning the symbol into a ConcreteInt, rather than ExprEngine.
// Test relational operators.
- if ((local + 1) < 2)
- malloc(1); // expected-warning{{never executed}}
- if (2 > (local + 1))
- malloc(1); // expected-warning{{never executed}}
+ clang_analyzer_eval((local + 1) >= 2); // expected-warning{{TRUE}}
+ clang_analyzer_eval(2 <= (local + 1)); // expected-warning{{TRUE}}
// Test equality operators.
- if ((local + 1) == 1)
- malloc(1); // expected-warning{{never executed}}
- if (1 == (local + 1))
- malloc(1); // expected-warning{{never executed}}
+ clang_analyzer_eval((local + 1) != 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(1 != (local + 1)); // expected-warning{{TRUE}}
}
void PR12206_truncation(signed char x) {
@@ -393,24 +236,19 @@ void PR12206_truncation(signed char x) {
signed int value = 1 + (1 << 8);
// Test relational operators.
- if ((local + 1) >= value)
- malloc(1); // expected-warning{{never executed}}
- if (value <= (local + 1))
- malloc(1); // expected-warning{{never executed}}
+ clang_analyzer_eval((local + 1) < value); // expected-warning{{TRUE}}
+ clang_analyzer_eval(value > (local + 1)); // expected-warning{{TRUE}}
// Test equality operators.
- if ((local + 1) == value)
- malloc(1); // expected-warning{{never executed}}
- if (value == (local + 1))
- malloc(1); // expected-warning{{never executed}}
+ clang_analyzer_eval((local + 1) != value); // expected-warning{{TRUE}}
+ clang_analyzer_eval(value != (local + 1)); // expected-warning{{TRUE}}
}
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.
+ // would see x < 8 and then declare the assertion to be known false.
if (x*4 < 8)
return;
- if (x == 3)
- malloc(1);
- return; // expected-warning{{leak}}
+
+ clang_analyzer_eval(x == 3); // expected-warning{{UNKNOWN}}
}
diff --git a/test/Analysis/array-struct-region.c b/test/Analysis/array-struct-region.c
index 18d5b2a375..c1eddcdd21 100644
--- a/test/Analysis/array-struct-region.c
+++ b/test/Analysis/array-struct-region.c
@@ -1,25 +1,21 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,experimental.deadcode.UnreachableCode -analyzer-store=region -analyzer-constraints=basic -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,experimental.deadcode.UnreachableCode -analyzer-store=region -analyzer-constraints=range -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify %s
+
+void clang_analyzer_eval(int);
int string_literal_init() {
char a[] = "abc";
char b[2] = "abc"; // expected-warning{{too long}}
char c[5] = "abc";
- if (a[1] != 'b')
- return 0; // expected-warning{{never executed}}
- if (b[1] != 'b')
- return 0; // expected-warning{{never executed}}
- if (c[1] != 'b')
- return 0; // expected-warning{{never executed}}
+ clang_analyzer_eval(a[1] == 'b'); // expected-warning{{TRUE}}
+ clang_analyzer_eval(b[1] == 'b'); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c[1] == 'b'); // expected-warning{{TRUE}}
- if (a[3] != 0)
- return 0; // expected-warning{{never executed}}
- if (c[3] != 0)
- return 0; // expected-warning{{never executed}}
+ clang_analyzer_eval(a[3] == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(c[3] == 0); // expected-warning{{TRUE}}
- if (c[4] != 0)
- return 0; // expected-warning{{never executed}}
+ clang_analyzer_eval(c[4] == 0); // expected-warning{{TRUE}}
return 42;
}
@@ -48,13 +44,16 @@ void nested_compound_literals_float(float rad) {
void struct_as_array() {
- struct simple { int x; };
+ struct simple { int x; int y; };
struct simple a;
struct simple *p = &a;
+
p->x = 5;
- if (!p[0].x)
- return; // expected-warning{{never executed}}
- if (p[0].x)
- return; // no-warning
+ clang_analyzer_eval(a.x == 5); // expected-warning{{TRUE}}
+ clang_analyzer_eval(p[0].x == 5); // expected-warning{{TRUE}}
+
+ p[0].y = 5;
+ clang_analyzer_eval(a.y == 5); // expected-warning{{TRUE}}
+ clang_analyzer_eval(p->y == 5); // expected-warning{{TRUE}}
}
diff --git a/test/Analysis/base-init.cpp b/test/Analysis/base-init.cpp
index 8fd7abcc37..ae99d53e20 100644
--- a/test/Analysis/base-init.cpp
+++ b/test/Analysis/base-init.cpp
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -analyzer-inline-call -cfg-add-initializers -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -cfg-add-initializers -verify %s
// XFAIL: *
+void clang_analyzer_eval(bool);
+
class A {
int x;
public:
@@ -24,8 +26,5 @@ B::B() {
void f() {
B b;
- if (b.getx() != 0) {
- int *p = 0;
- *p = 0; // no-warning
- }
+ clang_analyzer_eval(b.getx() == 0); // expected-warning{{TRUE}}
}
diff --git a/test/Analysis/bstring.c b/test/Analysis/bstring.c
index 87c91613a5..d383d421d4 100644
--- a/test/Analysis/bstring.c
+++ b/test/Analysis/bstring.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,experimental.unix.cstring -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,experimental.unix.cstring -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring.NullArg,experimental.unix.cstring.OutOfBounds,experimental.unix.cstring.BufferOverlap,experimental.unix.cstring.NotNullTerminated -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
//===----------------------------------------------------------------------===
// Declarations
@@ -26,6 +26,8 @@
typedef typeof(sizeof(int)) size_t;
+void clang_analyzer_eval(int);
+
//===----------------------------------------------------------------------===
// memcpy()
//===----------------------------------------------------------------------===
@@ -52,12 +54,11 @@ void memcpy0 () {
memcpy(dst, src, 4); // no-warning
- if (memcpy(dst, src, 4) != dst) {
- (void)*(char*)0; // no-warning
- }
+ clang_analyzer_eval(memcpy(dst, src, 4) == dst); // expected-warning{{TRUE}}
- if (dst[0] != 0)
- (void)*(char*)0; // expected-warning{{null}}
+ // If we actually model the copy, we can make this known.
+ // The important thing for now is that the old value has been invalidated.
+ clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
}
void memcpy1 () {
@@ -138,14 +139,13 @@ void memcpy13() {
void memcpy_unknown_size (size_t n) {
char a[4], b[4] = {1};
- if (memcpy(a, b, n) != a)
- (void)*(char*)0; // no-warning
+ clang_analyzer_eval(memcpy(a, b, n) == a); // expected-warning{{TRUE}}
}
void memcpy_unknown_size_warn (size_t n) {
char a[4];
- if (memcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}}
- (void)*(char*)0; // no-warning
+ void *result = memcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
+ clang_analyzer_eval(result == a); // no-warning (above is fatal)
}
//===----------------------------------------------------------------------===
@@ -174,12 +174,11 @@ void mempcpy0 () {
mempcpy(dst, src, 4); // no-warning
- if (mempcpy(dst, src, 4) != &dst[4]) {
- (void)*(char*)0; // no-warning
- }
+ clang_analyzer_eval(mempcpy(dst, src, 4) == &dst[4]); // expected-warning{{TRUE}}
- if (dst[0] != 0)
- (void)*(char*)0; // expected-warning{{null}}
+ // If we actually model the copy, we can make this known.
+ // The important thing for now is that the old value has been invalidated.
+ clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
}
void mempcpy1 () {
@@ -260,8 +259,8 @@ void mempcpy13() {
void mempcpy_unknown_size_warn (size_t n) {
char a[4];
- if (mempcpy(a, 0, n) != a) // expected-warning{{Null pointer argument in call to memory copy function}}
- (void)*(char*)0; // no-warning
+ void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
+ clang_analyzer_eval(result == a); // no-warning (above is fatal)
}
void mempcpy_unknownable_size (char *src, float n) {
@@ -295,12 +294,11 @@ void memmove0 () {
memmove(dst, src, 4); // no-warning
- if (memmove(dst, src, 4) != dst) {
- (void)*(char*)0; // no-warning
- }
+ clang_analyzer_eval(memmove(dst, src, 4) == dst); // expected-warning{{TRUE}}
- if (dst[0] != 0)
- (void)*(char*)0; // expected-warning{{null}}
+ // If we actually model the copy, we can make this known.
+ // The important thing for now is that the old value has been invalidated.
+ clang_analyzer_eval(dst[0] != 0); // expected-warning{{UNKNOWN}}
}
void memmove1 () {
@@ -327,7 +325,7 @@ void memmove2 () {
// __builtin_bcmp is not defined with const in Builtins.def.
int bcmp(/*const*/ void *s1, /*const*/ void *s2, size_t n);
#define memcmp bcmp
-
+//
#else /* VARIANT */
#define memcmp BUILTIN(memcmp)
@@ -360,34 +358,32 @@ void memcmp2 () {
void memcmp3 () {
char a[] = {1, 2, 3, 4};
- if (memcmp(a, a, 4))
- (void)*(char*)0; // no-warning
+ clang_analyzer_eval(memcmp(a, a, 4) == 0); // expected-warning{{TRUE}}
}
void memcmp4 (char *input) {
char a[] = {1, 2