mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-03 19:32:35 +00:00
[analyzer] Convert many existing tests to use clang_analyzer_eval.
llvm-svn: 156920
This commit is contained in:
parent
31ae259a41
commit
6d5a8caac3
@ -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}}
|
||||
}
|
||||
|
@ -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}}
|
||||
}
|
||||
|
@ -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}}
|
||||
}
|
||||
|
||||
|
@ -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}}
|
||||
}
|
||||
|
@ -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 () {
|
||||
|
@ -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}}
|
||||
}
|
||||
|
@ -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}}
|
||||
}
|
||||
|
@ -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}}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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}}
|
||||
}
|
||||
|
@ -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}}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user