[analyzer] Convert many existing tests to use clang_analyzer_eval.

llvm-svn: 156920
This commit is contained in:
Jordy Rose 2012-05-16 16:01:10 +00:00
parent 31ae259a41
commit 6d5a8caac3
11 changed files with 470 additions and 966 deletions

View File

@ -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}}
}

View File

@ -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
// 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);
// 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)
@ -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}}
clang_analyzer_eval(a == max && b != min); // expected-warning{{FALSE}}
}
void mixedWraparoundGT(int a) {
int max = INT_MAX;
if ((a + 2) > (max + 1LL))
return; // expected-warning{{never executed}}
}
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}}
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 mixedWraparoundLT(int a) {
int min = INT_MIN;
if ((a - 2) < (min - 1LL))
return; // expected-warning{{never executed}}
}
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}}
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 mixedWraparoundEQ(int a) {
void mixedWraparoundEQ_NE(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
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}}
}

View File

@ -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}}
}

View File

@ -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}}
}

View File

@ -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, 3, 4};
if (memcmp(a, input, 4))
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(memcmp(a, input, 4) == 0); // expected-warning{{UNKNOWN}}
}
void memcmp5 (char *input) {
char a[] = {1, 2, 3, 4};
if (memcmp(a, 0, 0)) // no-warning
(void)*(char*)0; // no-warning
if (memcmp(0, a, 0)) // no-warning
(void)*(char*)0; // no-warning
if (memcmp(a, input, 0)) // no-warning
(void)*(char*)0; // no-warning
clang_analyzer_eval(memcmp(a, 0, 0) == 0); // expected-warning{{TRUE}}
clang_analyzer_eval(memcmp(0, a, 0) == 0); // expected-warning{{TRUE}}
clang_analyzer_eval(memcmp(a, input, 0) == 0); // expected-warning{{TRUE}}
}
void memcmp6 (char *a, char *b, size_t n) {
int result = memcmp(a, b, n);
if (result != 0)
return;
if (n == 0)
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(n != 0); // expected-warning{{TRUE}}
// else
// analyzer_assert_unknown(n == 0);
// We can't do the above comparison because n has already been constrained.
// On one path n == 0, on the other n != 0.
}
int memcmp7 (char *a, size_t x, size_t y, size_t n) {
@ -411,8 +407,9 @@ void bcopy0 () {
bcopy(src, dst, 4); // no-warning
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 bcopy1 () {

View File

@ -1,7 +1,6 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
// Trigger a warning if the analyzer reaches this point in the control flow.
#define WARN ((void)*(char*)0)
void clang_analyzer_eval(int);
// There should be no warnings unless otherwise indicated.
@ -9,73 +8,71 @@ void testComparisons (int a) {
// Sema can already catch the simple comparison a==a,
// since that's usually a logic error (and not path-dependent).
int b = a;
if (!(b==a)) WARN; // expected-warning{{never executed}}
if (!(b>=a)) WARN; // expected-warning{{never executed}}
if (!(b<=a)) WARN; // expected-warning{{never executed}}
if (b!=a) WARN; // expected-warning{{never executed}}
if (b>a) WARN; // expected-warning{{never executed}}
if (b<a) WARN; // expected-warning{{never executed}}
clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
clang_analyzer_eval(b <= a); // expected-warning{{TRUE}}
clang_analyzer_eval(b != a); // expected-warning{{FALSE}}
clang_analyzer_eval(b > a); // expected-warning{{FALSE}}
clang_analyzer_eval(b < a); // expected-warning{{FALSE}}
}
void testSelfOperations (int a) {
if ((a|a) != a) WARN; // expected-warning{{never executed}}
if ((a&a) != a) WARN; // expected-warning{{never executed}}
if ((a^a) != 0) WARN; // expected-warning{{never executed}}
if ((a-a) != 0) WARN; // expected-warning{{never executed}}
clang_analyzer_eval((a|a) == a); // expected-warning{{TRUE}}
clang_analyzer_eval((a&a) == a); // expected-warning{{TRUE}}
clang_analyzer_eval((a^a) == 0); // expected-warning{{TRUE}}
clang_analyzer_eval((a-a) == 0); // expected-warning{{TRUE}}
}
void testIdempotent (int a) {
if ((a*1) != a) WARN; // expected-warning{{never executed}}
if ((a/1) != a) WARN; // expected-warning{{never executed}}
if ((a+0) != a) WARN; // expected-warning{{never executed}}
if ((a-0) != a) WARN; // expected-warning{{never executed}}
if ((a<<0) != a) WARN; // expected-warning{{never executed}}
if ((a>>0) != a) WARN; // expected-warning{{never executed}}
if ((a^0) != a) WARN; // expected-warning{{never executed}}
if ((a&(~0)) != a) WARN; // expected-warning{{never executed}}
if ((a|0) != a) WARN; // expected-warning{{never executed}}
clang_analyzer_eval((a*1) == a); // expected-warning{{TRUE}}
clang_analyzer_eval((a/1) == a); // expected-warning{{TRUE}}
clang_analyzer_eval((a+0) == a); // expected-warning{{TRUE}}
clang_analyzer_eval((a-0) == a); // expected-warning{{TRUE}}
clang_analyzer_eval((a<<0) == a); // expected-warning{{TRUE}}
clang_analyzer_eval((a>>0) == a); // expected-warning{{TRUE}}
clang_analyzer_eval((a^0) == a); // expected-warning{{TRUE}}
clang_analyzer_eval((a&(~0)) == a); // expected-warning{{TRUE}}
clang_analyzer_eval((a|0) == a); // expected-warning{{TRUE}}
}
void testReductionToConstant (int a) {
if ((a*0) != 0) WARN; // expected-warning{{never executed}}
if ((a&0) != 0) WARN; // expected-warning{{never executed}}
if ((a|(~0)) != (~0)) WARN; // expected-warning{{never executed}}
clang_analyzer_eval((a*0) == 0); // expected-warning{{TRUE}}
clang_analyzer_eval((a&0) == 0); // expected-warning{{TRUE}}
clang_analyzer_eval((a|(~0)) == (~0)); // expected-warning{{TRUE}}
}
void testSymmetricIntSymOperations (int a) {
if ((2+a) != (a+2)) WARN; // expected-warning{{never executed}}
if ((2*a) != (a*2)) WARN; // expected-warning{{never executed}}
if ((2&a) != (a&2)) WARN; // expected-warning{{never executed}}
if ((2^a) != (a^2)) WARN; // expected-warning{{never executed}}
if ((2|a) != (a|2)) WARN; // expected-warning{{never executed}}
clang_analyzer_eval((2+a) == (a+2)); // expected-warning{{TRUE}}
clang_analyzer_eval((2*a) == (a*2)); // expected-warning{{TRUE}}
clang_analyzer_eval((2&a) == (a&2)); // expected-warning{{TRUE}}
clang_analyzer_eval((2^a) == (a^2)); // expected-warning{{TRUE}}
clang_analyzer_eval((2|a) == (a|2)); // expected-warning{{TRUE}}
}
void testAsymmetricIntSymOperations (int a) {
if (((~0) >> a) != (~0)) WARN; // expected-warning{{never executed}}
if ((0 >> a) != 0) WARN; // expected-warning{{never executed}}
if ((0 << a) != 0) WARN; // expected-warning{{never executed}}
clang_analyzer_eval(((~0) >> a) == (~0)); // expected-warning{{TRUE}}
clang_analyzer_eval((0 >> a) == 0); // expected-warning{{TRUE}}
clang_analyzer_eval((0 << a) == 0); // expected-warning{{TRUE}}
// Unsigned right shift shifts in zeroes.
if ((((unsigned)(~0)) >> ((unsigned) a)) != ((unsigned)(~0)))
WARN; // expected-warning{{}}
clang_analyzer_eval(((~0U) >> a) != (~0U)); // expected-warning{{UNKNOWN}}
}
void testLocations (char *a) {
char *b = a;
if (!(b==a)) WARN; // expected-warning{{never executed}}
if (!(b>=a)) WARN; // expected-warning{{never executed}}
if (!(b<=a)) WARN; // expected-warning{{never executed}}
if (b!=a) WARN; // expected-warning{{never executed}}
if (b>a) WARN; // expected-warning{{never executed}}
if (b<a) WARN; // expected-warning{{never executed}}
if (b-a) WARN; // expected-warning{{never executed}}
clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
clang_analyzer_eval(b <= a); // expected-warning{{TRUE}}
clang_analyzer_eval(b != a); // expected-warning{{FALSE}}
clang_analyzer_eval(b > a); // expected-warning{{FALSE}}
clang_analyzer_eval(b < a); // expected-warning{{FALSE}}
}
void testMixedTypeComparisons (char a, unsigned long b) {
if (a != 0) return;
if (b != 0x100) return;
if (a > b) WARN; // expected-warning{{never executed}}
if (b < a) WARN; // expected-warning{{never executed}}
if (a == b) WARN; // expected-warning{{never executed}}
clang_analyzer_eval(a <= b); // expected-warning{{TRUE}}
clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
}

View File

@ -1,4 +1,6 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -cfg-add-initializers -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -cfg-add-initializers -verify %s
void clang_analyzer_eval(bool);
class A {
int x;
@ -7,8 +9,5 @@ public:
};
A::A() : x(0) {
if (x != 0) {
int *p = 0;
*p = 0; // no-warning
}
clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
}

View File

@ -1,6 +1,8 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-inline-call -analyzer-store region -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-store region -verify %s
// XFAIL: *
void clang_analyzer_eval(bool);
struct A {
int x;
A(int a) { x = a; }
@ -9,33 +11,15 @@ struct A {
void f1() {
A x(3);
if (x.getx() == 3) {
int *p = 0;
*p = 3; // expected-warning{{Dereference of null pointer}}
} else {
int *p = 0;
*p = 3; // no-warning
}
clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
}
void f2() {
const A &x = A(3);
if (x.getx() == 3) {
int *p = 0;
*p = 3; // expected-warning{{Dereference of null pointer}}
} else {
int *p = 0;
*p = 3; // no-warning
}
clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
}
void f3() {
const A &x = (A)3;
if (x.getx() == 3) {
int *p = 0;
*p = 3; // expected-warning{{Dereference of null pointer}}
} else {
int *p = 0;
*p = 3; // no-warning
}
clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
}

View File

@ -1,8 +1,7 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub -analyzer-store=region -verify -triple i686-apple-darwin9 %s
// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 %s
// Used to trigger warnings for unreachable paths.
#define WARN do { int a, b; int c = &b-&a; } while (0)
void clang_analyzer_eval(int);
void f1() {
int a[10];
@ -67,111 +66,48 @@ void f6(int *p, int *q) {
void null_operand(int *a) {
start:
// LHS is a label, RHS is NULL
if (&&start == 0)
WARN; // no-warning
if (&&start < 0)
WARN; // no-warning
if (&&start <= 0)
WARN; // no-warning
if (!(&&start != 0))
WARN; // no-warning
if (!(&&start > 0))
WARN; // no-warning
if (!(&&start >= 0))
WARN; // no-warning
if (!(&&start - 0))
WARN; // no-warning
clang_analyzer_eval(&&start != 0); // expected-warning{{TRUE}}
clang_analyzer_eval(&&start >= 0); // expected-warning{{TRUE}}
clang_analyzer_eval(&&start > 0); // expected-warning{{TRUE}}
clang_analyzer_eval((&&start - 0) != 0); // expected-warning{{TRUE}}
// LHS is a non-symbolic value, RHS is NULL
if (&a == 0)
WARN; // no-warning
if (&a < 0)
WARN; // no-warning
if (&a <= 0)
WARN; // no-warning
if (!(&a != 0))
WARN; // no-warning
if (!(&a > 0))
WARN; // no-warning
if (!(&a >= 0))
WARN; // no-warning
if (!(&a - 0)) // expected-warning{{Pointer arithmetic done on non-array variables}}
WARN; // no-warning
clang_analyzer_eval(&a != 0); // expected-warning{{TRUE}}
clang_analyzer_eval(&a >= 0); // expected-warning{{TRUE}}
clang_analyzer_eval(&a > 0); // expected-warning{{TRUE}}
clang_analyzer_eval((&a - 0) != 0); // expected-warning{{TRUE}} expected-warning{{Pointer arithmetic done on non-array variables}}
// LHS is NULL, RHS is non-symbolic
// The same code is used for labels and non-symbolic values.
if (0 == &a)
WARN; // no-warning
if (0 > &a)
WARN; // no-warning
if (0 >= &a)
WARN; // no-warning
if (!(0 != &a))
WARN; // no-warning
if (!(0 < &a))
WARN; // no-warning
if (!(0 <= &a))
WARN; // no-warning
clang_analyzer_eval(0 != &a); // expected-warning{{TRUE}}
clang_analyzer_eval(0 <= &a); // expected-warning{{TRUE}}
clang_analyzer_eval(0 < &a); // expected-warning{{TRUE}}
// LHS is a symbolic value, RHS is NULL
if (a == 0)
WARN; // expected-warning{{}}
if (a < 0)
WARN; // no-warning
if (a <= 0)
WARN; // expected-warning{{}}
if (!(a != 0))
WARN; // expected-warning{{}}
if (!(a > 0))
WARN; // expected-warning{{}}
if (!(a >= 0))
WARN; // no-warning
if (!(a - 0))
WARN; // expected-warning{{}}
clang_analyzer_eval(a != 0); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(a >= 0); // expected-warning{{TRUE}}
clang_analyzer_eval(a <= 0); // expected-warning{{UNKNOWN}}
clang_analyzer_eval((a - 0) != 0); // expected-warning{{UNKNOWN}}
// LHS is NULL, RHS is a symbolic value
if (0 == a)
WARN; // expected-warning{{}}
if (0 > a)
WARN; // no-warning
if (0 >= a)
WARN; // expected-warning{{}}
if (!(0 != a))
WARN; // expected-warning{{}}
if (!(0 < a))
WARN; // expected-warning{{}}
if (!(0 <= a))
WARN; // no-warning
clang_analyzer_eval(0 != a); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(0 <= a); // expected-warning{{TRUE}}
clang_analyzer_eval(0 < a); // expected-warning{{UNKNOWN}}
}
void const_locs() {
char *a = (char*)0x1000;
char *b = (char*)0x1100;
start:
if (a==b)
WARN; // no-warning
if (!(a!=b))
WARN; // no-warning
if (a>b)
WARN; // no-warning
if (b<a)
WARN; // no-warning
if (a>=b)
WARN; // no-warning
if (b<=a)
WARN; // no-warning
if (b-a != 0x100)
WARN; // no-warning
clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
clang_analyzer_eval(a < b); // expected-warning{{TRUE}}
clang_analyzer_eval(a <= b); // expected-warning{{TRUE}}
clang_analyzer_eval((b-a) == 0x100); // expected-warning{{TRUE}}
if (&&start == a)
WARN; // expected-warning{{}}
if (a == &&start)
WARN; // expected-warning{{}}
if (&a == (char**)a)
WARN; // expected-warning{{}}
if ((char**)a == &a)
WARN; // expected-warning{{}}
clang_analyzer_eval(&&start == a); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(a == &&start); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(&a == (char**)a); // expected-warning{{UNKNOWN}}
clang_analyzer_eval((char**)a == &a); // expected-warning{{UNKNOWN}}
}
void array_matching_types() {
@ -179,20 +115,10 @@ void array_matching_types() {
int *a = &array[2];
int *b = &array[5];
if (a==b)
WARN; // no-warning
if (!(a!=b))
WARN; // no-warning
if (a>b)
WARN; // no-warning
if (b<a)
WARN; // no-warning
if (a>=b)
WARN; // no-warning
if (b<=a)
WARN; // no-warning
if ((b-a) == 0)
WARN; // no-warning
clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
clang_analyzer_eval(a < b); // expected-warning{{TRUE}}
clang_analyzer_eval(a <= b); // expected-warning{{TRUE}}
clang_analyzer_eval((b-a) != 0); // expected-warning{{TRUE}}
}
// This takes a different code path than array_matching_types()
@ -201,49 +127,22 @@ void array_different_types() {
int *a = &array[2];
char *b = (char*)&array[5];
if (a==b) // expected-warning{{comparison of distinct pointer types}}
WARN; // no-warning
if (!(a!=b)) // expected-warning{{comparison of distinct pointer types}}
WARN; // no-warning
if (a>b) // expected-warning{{comparison of distinct pointer types}}
WARN; // no-warning
if (b<a) // expected-warning{{comparison of distinct pointer types}}
WARN; // no-warning
if (a>=b) // expected-warning{{comparison of distinct pointer types}}
WARN; // no-warning
if (b<=a) // expected-warning{{comparison of distinct pointer types}}
WARN; // no-warning
clang_analyzer_eval(a != b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
clang_analyzer_eval(a < b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
clang_analyzer_eval(a <= b); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
}
struct test { int x; int y; };
void struct_fields() {
struct test a, b;
if (&a.x == &a.y)
WARN; // no-warning
if (!(&a.x != &a.y))
WARN; // no-warning
if (&a.x > &a.y)
WARN; // no-warning
if (&a.y < &a.x)
WARN; // no-warning
if (&a.x >= &a.y)
WARN; // no-warning
if (&a.y <= &a.x)
WARN; // no-warning
clang_analyzer_eval(&a.x != &a.y); // expected-warning{{TRUE}}
clang_analyzer_eval(&a.x < &a.y); // expected-warning{{TRUE}}
clang_analyzer_eval(&a.x <= &a.y); // expected-warning{{TRUE}}
if (&a.x == &b.x)
WARN; // no-warning
if (!(&a.x != &b.x))
WARN; // no-warning
if (&a.x > &b.x)
WARN; // expected-warning{{}}
if (&b.x < &a.x)
WARN; // expected-warning{{}}
if (&a.x >= &b.x)
WARN; // expected-warning{{}}
if (&b.x <= &a.x)
WARN; // expected-warning{{}}
clang_analyzer_eval(&a.x != &b.x); // expected-warning{{TRUE}}
clang_analyzer_eval(&a.x > &b.x); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(&a.x >= &b.x); // expected-warning{{UNKNOWN}}
}
void mixed_region_types() {
@ -251,35 +150,17 @@ void mixed_region_types() {
int array[2];
void *a = &array, *b = &s;
if (&a == &b)
WARN; // no-warning
if (!(&a != &b))
WARN; // no-warning
if (&a > &b)
WARN; // expected-warning{{}}
if (&b < &a)
WARN; // expected-warning{{}}
if (&a >= &b)
WARN; // expected-warning{{}}
if (&b <= &a)
WARN; // expected-warning{{}}
clang_analyzer_eval(&a != &b); // expected-warning{{TRUE}}
clang_analyzer_eval(&a > &b); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(&a >= &b); // expected-warning{{UNKNOWN}}
}
void symbolic_region(int *p) {
int a;
if (&a == p)
WARN; // no-warning
if (&a != p)
WARN; // expected-warning{{}}
if (&a > p)
WARN; // expected-warning{{}}
if (&a < p)
WARN; // expected-warning{{}}
if (&a >= p)
WARN; // expected-warning{{}}
if (&a <= p)
WARN; // expected-warning{{}}
clang_analyzer_eval(&a != p); // expected-warning{{TRUE}}
clang_analyzer_eval(&a > p); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(&a >= p); // expected-warning{{UNKNOWN}}
}
void PR7527 (int *p) {

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.unix.CString,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,experimental.unix.CString,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
// XFAIL: *
// This file is for tests that may eventually go into string.c, or may be
@ -32,6 +32,7 @@
#define NULL 0
typedef typeof(sizeof(int)) size_t;
void clang_analyzer_eval(int);
//===----------------------------------------------------------------------===
// strnlen()
@ -43,8 +44,7 @@ size_t strnlen(const char *s, size_t maxlen);
void strnlen_liveness(const char *x) {
if (strnlen(x, 10) < 5)
return;
if (strnlen(x, 10) < 5)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strnlen(x, 10) < 5); // expected-warning{{FALSE}}
}
void strnlen_subregion() {
@ -57,43 +57,43 @@ void strnlen_subregion() {
size_t a = strnlen(z.a, 10);
z.b[0] = 5;
size_t b = strnlen(z.a, 10);
if (a == 0 && b != 0)
(void)*(char*)0; // expected-warning{{never executed}}
if (a == 0)
clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
use_two_stringsn(&z);
size_t c = strnlen(z.a, 10);
if (a == 0 && c != 0)
(void)*(char*)0; // expected-warning{{null}}
if (a == 0)
clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
}
extern void use_stringn(char *);
void strnlen_argument(char *x) {
size_t a = strnlen(x, 10);
size_t b = strnlen(x, 10);
if (a == 0 && b != 0)
(void)*(char*)0; // expected-warning{{never executed}}
if (a == 0)
clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
use_stringn(x);
size_t c = strnlen(x, 10);
if (a == 0 && c != 0)
(void)*(char*)0; // expected-warning{{null}}
if (a == 0)
clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
}
extern char global_strn[];
void strnlen_global() {
size_t a = strnlen(global_strn, 10);
size_t b = strnlen(global_strn, 10);
if (a == 0 && b != 0)
(void)*(char*)0; // expected-warning{{never executed}}
if (a == 0)
clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
// Call a function with unknown effects, which should invalidate globals.
use_stringn(0);
size_t c = strnlen(global_strn, 10);
if (a == 0 && c != 0)
(void)*(char*)0; // expected-warning{{null}}
if (a == 0)
clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
}
void strnlen_indirect(char *x) {
@ -101,13 +101,13 @@ void strnlen_indirect(char *x) {
char *p = x;
char **p2 = &p;
size_t b = strnlen(x, 10);
if (a == 0 && b != 0)
(void)*(char*)0; // expected-warning{{never executed}}
if (a == 0)
clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
extern void use_stringn_ptr(char*const*);
use_stringn_ptr(p2);
size_t c = strnlen(x, 10);
if (a == 0 && c != 0)
(void)*(char*)0; // expected-warning{{null}}
if (a == 0)
clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
}

View File

@ -1,7 +1,7 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,experimental.unix.cstring,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,experimental.unix.cstring,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring,experimental.deadcode.UnreachableCode -analyzer-store=region -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=experimental.security.taint,core,unix.cstring,experimental.unix.cstring,experimental.deadcode.UnreachableCode -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 -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=experimental.security.taint,core,unix.cstring,experimental.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
//===----------------------------------------------------------------------===
// Declarations
@ -26,6 +26,9 @@
#define NULL 0
typedef typeof(sizeof(int)) size_t;
void clang_analyzer_eval(int);
int scanf(const char *restrict format, ...);
//===----------------------------------------------------------------------===
@ -36,23 +39,20 @@ int scanf(const char *restrict format, ...);
size_t strlen(const char *s);
void strlen_constant0() {
if (strlen("123") != 3)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen("123") == 3); // expected-warning{{TRUE}}
}
void strlen_constant1() {
const char *a = "123";
if (strlen(a) != 3)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
}
void strlen_constant2(char x) {
char a[] = "123";
if (strlen(a) != 3)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen(a) == 3); // expected-warning{{TRUE}}
a[0] = x;
if (strlen(a) != 3)
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(strlen(a) == 3); // expected-warning{{UNKNOWN}}
}
size_t strlen_null() {
@ -78,43 +78,46 @@ void strlen_subregion() {
size_t a = strlen(z.a);
z.b[0] = 5;
size_t b = strlen(z.a);
if (a == 0 && b != 0)
(void)*(char*)0; // expected-warning{{never executed}}
if (a == 0)
clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
use_two_strings(&z);
size_t c = strlen(z.a);
if (a == 0 && c != 0)
(void)*(char*)0; // expected-warning{{null}}
if (a == 0)
clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
}
extern void use_string(char *);
void strlen_argument(char *x) {
size_t a = strlen(x);
size_t b = strlen(x);
if (a == 0 && b != 0)
(void)*(char*)0; // expected-warning{{never executed}}
if (a == 0)
clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
use_string(x);
size_t c = strlen(x);
if (a == 0 && c != 0)
(void)*(char*)0; // expected-warning{{null}}
if (a == 0)
clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
}
extern char global_str[];
void strlen_global() {
size_t a = strlen(global_str);
size_t b = strlen(global_str);
if (a == 0 && b != 0)
(void)*(char*)0; // expected-warning{{never executed}}
if (a == 0) {
clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
// Make sure clang_analyzer_eval does not invalidate globals.
clang_analyzer_eval(strlen(global_str) == 0); // expected-warning{{TRUE}}
}
// Call a function with unknown effects, which should invalidate globals.
use_string(0);
size_t c = strlen(global_str);
if (a == 0 && c != 0)
(void)*(char*)0; // expected-warning{{null}}
if (a == 0)
clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
}
void strlen_indirect(char *x) {
@ -122,15 +125,15 @@ void strlen_indirect(char *x) {
char *p = x;
char **p2 = &p;
size_t b = strlen(x);
if (a == 0 && b != 0)
(void)*(char*)0; // expected-warning{{never executed}}
if (a == 0)
clang_analyzer_eval(b == 0); // expected-warning{{TRUE}}
extern void use_string_ptr(char*const*);
use_string_ptr(p2);
size_t c = strlen(x);
if (a == 0 && c != 0)
(void)*(char*)0; // expected-warning{{null}}
if (a == 0)
clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
}
void strlen_indirect2(char *x) {
@ -141,15 +144,14 @@ void strlen_indirect2(char *x) {
use_string_ptr2(p2);
size_t c = strlen(x);
if (a == 0 && c != 0)
(void)*(char*)0; // expected-warning{{null}}
if (a == 0)
clang_analyzer_eval(c == 0); // expected-warning{{UNKNOWN}}
}
void strlen_liveness(const char *x) {
if (strlen(x) < 5)
return;
if (strlen(x) < 5)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen(x) < 5); // expected-warning{{FALSE}}
}
//===----------------------------------------------------------------------===
@ -159,43 +161,35 @@ void strlen_liveness(const char *x) {
size_t strnlen(const char *s, size_t maxlen);
void strnlen_constant0() {
if (strnlen("123", 10) != 3)
(void)*(char*)0; // expected-warning{{never executed}}
clang_analyzer_eval(strnlen("123", 10) == 3); // expected-warning{{TRUE}}
}
void strnlen_constant1() {
const char *a = "123";
if (strnlen(a, 10) != 3)
(void)*(char*)0; // expected-warning{{never executed}}
clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
}
void strnlen_constant2(char x) {
char a[] = "123";
if (strnlen(a, 10) != 3)
(void)*(char*)0; // expected-warning{{never executed}}
clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{TRUE}}
a[0] = x;
if (strnlen(a, 10) != 3)
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(strnlen(a, 10) == 3); // expected-warning{{UNKNOWN}}
}
void strnlen_constant4() {
if (strnlen("123456", 3) != 3)
(void)*(char*)0; // expected-warning{{never executed}}
clang_analyzer_eval(strnlen("123456", 3) == 3); // expected-warning{{TRUE}}
}
void strnlen_constant5() {
const char *a = "123456";
if (strnlen(a, 3) != 3)
(void)*(char*)0; // expected-warning{{never executed}}
clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
}
void strnlen_constant6(char x) {
char a[] = "123456";
if (strnlen(a, 3) != 3)
(void)*(char*)0; // expected-warning{{never executed}}
clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{TRUE}}
a[0] = x;
if (strnlen(a, 3) != 3)
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(strnlen(a, 3) == 3); // expected-warning{{UNKNOWN}}
}
size_t strnlen_null() {
@ -212,10 +206,8 @@ label:
}
void strnlen_zero() {
if (strnlen("abc", 0) != 0)
(void)*(char*)0; // expected-warning{{never executed}}
if (strnlen(NULL, 0) != 0) // no-warning
(void)*(char*)0; // no-warning
clang_analyzer_eval(strnlen("abc", 0) == 0); // expected-warning{{TRUE}}
clang_analyzer_eval(strnlen(NULL, 0) == 0); // expected-warning{{TRUE}}
}
size_t strnlen_compound_literal() {
@ -230,40 +222,26 @@ size_t strnlen_unknown_limit(float f) {
}
void strnlen_is_not_strlen(char *x) {
if (strnlen(x, 10) != strlen(x))
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(strnlen(x, 10) == strlen(x)); // expected-warning{{UNKNOWN}}
}
void strnlen_at_limit(char *x) {
size_t len = strnlen(x, 10);
if (len > 10)
(void)*(char*)0; // expected-warning{{never executed}}
if (len == 10)
(void)*(char*)0; // expected-warning{{null}}
}
void strnlen_less_than_limit(char *x) {
size_t len = strnlen(x, 10);
if (len > 10)
(void)*(char*)0; // expected-warning{{never executed}}
if (len < 10)
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(len <= 10); // expected-warning{{TRUE}}
clang_analyzer_eval(len == 10); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(len < 10); // expected-warning{{UNKNOWN}}
}
void strnlen_at_actual(size_t limit) {
size_t len = strnlen("abc", limit);
if (len > 3)
(void)*(char*)0; // expected-warning{{never executed}}
if (len == 3)
(void)*(char*)0; // expected-warning{{null}}
}
void strnlen_less_than_actual(size_t limit) {
size_t len = strnlen("abc", limit);
if (len > 3)
(void)*(char*)0; // expected-warning{{never executed}}
if (len < 3)
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(len <= 3); // expected-warning{{TRUE}}
// This is due to eager assertion in strnlen.
if (limit == 0) {
clang_analyzer_eval(len == 0); // expected-warning{{TRUE}}
} else {
clang_analyzer_eval(len == 3); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(len < 3); // expected-warning{{UNKNOWN}}
}
}
//===----------------------------------------------------------------------===
@ -304,14 +282,9 @@ void strcpy_fn_const(char *x) {
void strcpy_effects(char *x, char *y) {
char a = x[0];
if (strcpy(x, y) != x)
(void)*(char*)0; // no-warning
if (strlen(x) != strlen(y))
(void)*(char*)0; // no-warning
if (a != x[0])
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(strcpy(x, y) == x); // expected-warning{{TRUE}}
clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
}
void strcpy_overflow(char *y) {
@ -348,14 +321,9 @@ char *stpcpy(char *restrict s1, const char *restrict s2);
void stpcpy_effect(char *x, char *y) {
char a = x[0];
if (stpcpy(x, y) != &x[strlen(y)])
(void)*(char*)0; // no-warning
if (strlen(x) != strlen(y))
(void)*(char*)0; // no-warning
if (a != x[0])
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(stpcpy(x, y) == &x[strlen(y)]); // expected-warning{{TRUE}}
clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{TRUE}}
clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
}
void stpcpy_overflow(char *y) {
@ -409,11 +377,8 @@ void strcat_effects(char *y) {
if (strlen(y) != 4)
return;
if (strcat(x, y) != x)
(void)*(char*)0; // no-warning
if ((int)strlen(x) != (orig_len + strlen(y)))
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcat(x, y) == x); // expected-warning{{TRUE}}
clang_analyzer_eval((int)strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
}
void strcat_overflow_0(char *y) {
@ -442,29 +407,25 @@ void strcat_no_overflow(char *y) {
void strcat_symbolic_dst_length(char *dst) {
strcat(dst, "1234");
if (strlen(dst) < 4)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
}
void strcat_symbolic_src_length(char *src) {
char dst[8] = "1234";
strcat(dst, src);
if (strlen(dst) < 4)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
}
void strcat_symbolic_dst_length_taint(char *dst) {
scanf("%s", dst); // Taint data.
strcat(dst, "1234");
if (strlen(dst) < 4)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
}
void strcat_unknown_src_length(char *src, int offset) {
char dst[8] = "1234";
strcat(dst, &src[offset]);
if (strlen(dst) < 4)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
}
// There is no strcat_unknown_dst_length because if we can't get a symbolic
@ -513,14 +474,9 @@ void strncpy_fn(char *x) {
void strncpy_effects(char *x, char *y) {
char a = x[0];
if (strncpy(x, y, 5) != x)
(void)*(char*)0; // no-warning
if (strlen(x) != strlen(y))
(void)*(char*)0; // expected-warning{{null}}
if (a != x[0])
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(strncpy(x, y, 5) == x); // expected-warning{{TRUE}}
clang_analyzer_eval(strlen(x) == strlen(y)); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(a == x[0]); // expected-warning{{UNKNOWN}}
}
void strncpy_overflow(char *y) {
@ -562,8 +518,7 @@ void strncpy_exactly_matching_buffer(char *y) {
// strncpy does not null-terminate, so we have no idea what the strlen is
// after this.
if (strlen(x) > 4)
(void)*(int*)0; // expected-warning{{null}}
clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}}
}
void strncpy_exactly_matching_buffer2(char *y) {
@ -574,8 +529,7 @@ void strncpy_exactly_matching_buffer2(char *y) {
strncpy(x, y, 4); // no-warning
// This time, we know that y fits in x anyway.
if (strlen(x) > 3)
(void)*(int*)0; // no-warning
clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{TRUE}}
}
void strncpy_zero(char *src) {
@ -628,11 +582,8 @@ void strncat_effects(char *y) {
if (strlen(y) != 4)
return;
if (strncat(x, y, strlen(y)) != x)
(void)*(char*)0; // no-warning
if (strlen(x) != orig_len + strlen(y))
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncat(x, y, strlen(y)) == x); // expected-warning{{TRUE}}
clang_analyzer_eval(strlen(x) == (orig_len + strlen(y))); // expected-warning{{TRUE}}
}
void strncat_overflow_0(char *y) {
@ -672,15 +623,13 @@ void strncat_no_overflow_2(char *y) {
void strncat_symbolic_dst_length(char *dst) {
strncat(dst, "1234", 5);
if (strlen(dst) < 4)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
}
void strncat_symbolic_src_length(char *src) {
char dst[8] = "1234";
strncat(dst, src, 3);
if (strlen(dst) < 4)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
char dst2[8] = "1234";
strncat(dst2, src, 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
@ -689,8 +638,7 @@ void strncat_symbolic_src_length(char *src) {
void strncat_unknown_src_length(char *src, int offset) {
char dst[8] = "1234";
strncat(dst, &src[offset], 3);
if (strlen(dst) < 4)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
char dst2[8] = "1234";
strncat(dst2, &src[offset], 4); // expected-warning{{Size argument is greater than the free space in the destination buffer}}
@ -703,20 +651,18 @@ void strncat_symbolic_limit(unsigned limit) {
char dst[6] = "1234";
char src[] = "567";
strncat(dst, src, limit); // no-warning
if (strlen(dst) < 4)
(void)*(char*)0; // no-warning
if (strlen(dst) == 4)
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
}
void strncat_unknown_limit(float limit) {
char dst[6] = "1234";
char src[] = "567";
strncat(dst, src, (size_t)limit); // no-warning
if (strlen(dst) < 4)
(void)*(char*)0; // no-warning
if (strlen(dst) == 4)
(void)*(char*)0; // expected-warning{{null}}
clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}}
clang_analyzer_eval(strlen(dst) == 4); // expected-warning{{UNKNOWN}}
}
void strncat_too_big(char *dst, char *src) {
@ -746,41 +692,35 @@ void strncat_empty() {
int strcmp(const char * s1, const char * s2);
void strcmp_constant0() {
if (strcmp("123", "123") != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp("123", "123") == 0); // expected-warning{{TRUE}}
}
void strcmp_constant_and_var_0() {
char *x = "123";
if (strcmp(x, "123") != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp(x, "123") == 0); // expected-warning{{TRUE}}
}
void strcmp_constant_and_var_1() {
char *x = "123";
if (strcmp("123", x) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp("123", x) == 0); // expected-warning{{TRUE}}
}
void strcmp_0() {
char *x = "123";
char *y = "123";
if (strcmp(x, y) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp(x, y) == 0); // expected-warning{{TRUE}}
}
void strcmp_1() {
char *x = "234";
char *y = "123";
if (strcmp(x, y) != 1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
}
void strcmp_2() {
char *x = "123";
char *y = "234";
if (strcmp(x, y) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
}
void strcmp_null_0() {
@ -798,39 +738,33 @@ void strcmp_null_1() {
void strcmp_diff_length_0() {
char *x = "12345";
char *y = "234";
if (strcmp(x, y) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
}
void strcmp_diff_length_1() {
char *x = "123";
char *y = "23456";
if (strcmp(x, y) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
}
void strcmp_diff_length_2() {
char *x = "12345";
char *y = "123";
if (strcmp(x, y) != 1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp(x, y) == 1); // expected-warning{{TRUE}}
}
void strcmp_diff_length_3() {
char *x = "123";
char *y = "12345";
if (strcmp(x, y) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp(x, y) == -1); // expected-warning{{TRUE}}
}
void strcmp_embedded_null () {
if (strcmp("\0z", "\0y") != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp("\0z", "\0y") == 0); // expected-warning{{TRUE}}
}
void strcmp_unknown_arg (char *unknown) {
if (strcmp(unknown, unknown) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcmp(unknown, unknown) == 0); // expected-warning{{TRUE}}
}
//===----------------------------------------------------------------------===
@ -841,41 +775,35 @@ void strcmp_unknown_arg (char *unknown) {
int strncmp(const char *s1, const char *s2, size_t n);
void strncmp_constant0() {
if (strncmp("123", "123", 3) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp("123", "123", 3) == 0); // expected-warning{{TRUE}}
}
void strncmp_constant_and_var_0() {
char *x = "123";
if (strncmp(x, "123", 3) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, "123", 3) == 0); // expected-warning{{TRUE}}
}
void strncmp_constant_and_var_1() {
char *x = "123";
if (strncmp("123", x, 3) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp("123", x, 3) == 0); // expected-warning{{TRUE}}
}
void strncmp_0() {
char *x = "123";
char *y = "123";
if (strncmp(x, y, 3) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
}
void strncmp_1() {
char *x = "234";
char *y = "123";
if (strncmp(x, y, 3) != 1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
}
void strncmp_2() {
char *x = "123";
char *y = "234";
if (strncmp(x, y, 3) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
}
void strncmp_null_0() {
@ -893,55 +821,47 @@ void strncmp_null_1() {
void strncmp_diff_length_0() {
char *x = "12345";
char *y = "234";
if (strncmp(x, y, 5) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
}
void strncmp_diff_length_1() {
char *x = "123";
char *y = "23456";
if (strncmp(x, y, 5) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
}
void strncmp_diff_length_2() {
char *x = "12345";
char *y = "123";
if (strncmp(x, y, 5) != 1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, y, 5) == 1); // expected-warning{{TRUE}}
}
void strncmp_diff_length_3() {
char *x = "123";
char *y = "12345";
if (strncmp(x, y, 5) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, y, 5) == -1); // expected-warning{{TRUE}}
}
void strncmp_diff_length_4() {
char *x = "123";
char *y = "12345";
if (strncmp(x, y, 3) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, y, 3) == 0); // expected-warning{{TRUE}}
}
void strncmp_diff_length_5() {
char *x = "012";
char *y = "12345";
if (strncmp(x, y, 3) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, y, 3) == -1); // expected-warning{{TRUE}}
}
void strncmp_diff_length_6() {
char *x = "234";
char *y = "12345";
if (strncmp(x, y, 3) != 1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp(x, y, 3) == 1); // expected-warning{{TRUE}}
}
void strncmp_embedded_null () {
if (strncmp("ab\0zz", "ab\0yy", 4) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
}
//===----------------------------------------------------------------------===
@ -952,41 +872,35 @@ void strncmp_embedded_null () {
int strcasecmp(const char *s1, const char *s2);
void strcasecmp_constant0() {
if (strcasecmp("abc", "Abc") != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp("abc", "Abc") == 0); // expected-warning{{TRUE}}
}
void strcasecmp_constant_and_var_0() {
char *x = "abc";
if (strcasecmp(x, "Abc") != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp(x, "Abc") == 0); // expected-warning{{TRUE}}
}
void strcasecmp_constant_and_var_1() {
char *x = "abc";
if (strcasecmp("Abc", x) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp("Abc", x) == 0); // expected-warning{{TRUE}}
}
void strcasecmp_0() {
char *x = "abc";
char *y = "Abc";
if (strcasecmp(x, y) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp(x, y) == 0); // expected-warning{{TRUE}}
}
void strcasecmp_1() {
char *x = "Bcd";
char *y = "abc";
if (strcasecmp(x, y) != 1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
}
void strcasecmp_2() {
char *x = "abc";
char *y = "Bcd";
if (strcasecmp(x, y) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
}
void strcasecmp_null_0() {
@ -1004,34 +918,29 @@ void strcasecmp_null_1() {
void strcasecmp_diff_length_0() {
char *x = "abcde";
char *y = "aBd";
if (strcasecmp(x, y) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
}
void strcasecmp_diff_length_1() {
char *x = "abc";
char *y = "aBdef";
if (strcasecmp(x, y) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
}
void strcasecmp_diff_length_2() {
char *x = "aBcDe";
char *y = "abc";
if (strcasecmp(x, y) != 1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp(x, y) == 1); // expected-warning{{TRUE}}
}
void strcasecmp_diff_length_3() {
char *x = "aBc";
char *y = "abcde";
if (strcasecmp(x, y) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp(x, y) == -1); // expected-warning{{TRUE}}
}
void strcasecmp_embedded_null () {
if (strcasecmp("ab\0zz", "ab\0yy") != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strcasecmp("ab\0zz", "ab\0yy") == 0); // expected-warning{{TRUE}}
}
//===----------------------------------------------------------------------===
@ -1042,41 +951,35 @@ void strcasecmp_embedded_null () {
int strncasecmp(const char *s1, const char *s2, size_t n);
void strncasecmp_constant0() {
if (strncasecmp("abc", "Abc", 3) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp("abc", "Abc", 3) == 0); // expected-warning{{TRUE}}
}
void strncasecmp_constant_and_var_0() {
char *x = "abc";
if (strncasecmp(x, "Abc", 3) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, "Abc", 3) == 0); // expected-warning{{TRUE}}
}
void strncasecmp_constant_and_var_1() {
char *x = "abc";
if (strncasecmp("Abc", x, 3) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp("Abc", x, 3) == 0); // expected-warning{{TRUE}}
}
void strncasecmp_0() {
char *x = "abc";
char *y = "Abc";
if (strncasecmp(x, y, 3) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
}
void strncasecmp_1() {
char *x = "Bcd";
char *y = "abc";
if (strncasecmp(x, y, 3) != 1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
}
void strncasecmp_2() {
char *x = "abc";
char *y = "Bcd";
if (strncasecmp(x, y, 3) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
}
void strncasecmp_null_0() {
@ -1094,55 +997,47 @@ void strncasecmp_null_1() {
void strncasecmp_diff_length_0() {
char *x = "abcde";
char *y = "aBd";
if (strncasecmp(x, y, 5) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
}
void strncasecmp_diff_length_1() {
char *x = "abc";
char *y = "aBdef";
if (strncasecmp(x, y, 5) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
}
void strncasecmp_diff_length_2() {
char *x = "aBcDe";
char *y = "abc";
if (strncasecmp(x, y, 5) != 1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, y, 5) == 1); // expected-warning{{TRUE}}
}
void strncasecmp_diff_length_3() {
char *x = "aBc";
char *y = "abcde";
if (strncasecmp(x, y, 5) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, y, 5) == -1); // expected-warning{{TRUE}}
}
void strncasecmp_diff_length_4() {
char *x = "abcde";
char *y = "aBc";
if (strncasecmp(x, y, 3) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, y, 3) == 0); // expected-warning{{TRUE}}
}
void strncasecmp_diff_length_5() {
char *x = "abcde";
char *y = "aBd";
if (strncasecmp(x, y, 3) != -1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, y, 3) == -1); // expected-warning{{TRUE}}
}
void strncasecmp_diff_length_6() {
char *x = "aBDe";
char *y = "abc";
if (strncasecmp(x, y, 3) != 1)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp(x, y, 3) == 1); // expected-warning{{TRUE}}
}
void strncasecmp_embedded_null () {
if (strncasecmp("ab\0zz", "ab\0yy", 4) != 0)
(void)*(char*)0; // no-warning
clang_analyzer_eval(strncasecmp("ab\0zz", "ab\0yy", 4) == 0); // expected-warning{{TRUE}}
}
//===----------------------------------------------------------------------===
@ -1169,10 +1064,10 @@ void PR12206(const char *x) {
if (strlen(x) != value) return;
// Test relational operators.
if (strlen(x) < 2) { (void)*(char*)0; } // no-warning
if (2 > strlen(x)) { (void)*(char*)0; } // no-warning
clang_analyzer_eval(strlen(x) >= 2); // expected-warning{{TRUE}}
clang_analyzer_eval(2 <= strlen(x)); // expected-warning{{TRUE}}
// Test equality operators.
if (strlen(x) == 1) { (void)*(char*)0; } // no-warning
if (1 == strlen(x)) { (void)*(char*)0; } // no-warning
clang_analyzer_eval(strlen(x) != 1); // expected-warning{{TRUE}}
clang_analyzer_eval(1 != strlen(x)); // expected-warning{{TRUE}}
}