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