diff options
Diffstat (limited to 'test/Analysis')
99 files changed, 15855 insertions, 1654 deletions
diff --git a/test/Analysis/MissingDealloc.m b/test/Analysis/MissingDealloc.m index 51a5912d4443..589fcf57f40c 100644 --- a/test/Analysis/MissingDealloc.m +++ b/test/Analysis/MissingDealloc.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.osx.cocoa.Dealloc '-DIBOutlet=__attribute__((iboutlet))' %s -verify +// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.osx.cocoa.Dealloc %s -verify typedef signed char BOOL; @protocol NSObject - (BOOL)isEqual:(id)object; @@ -53,10 +53,6 @@ typedef struct objc_selector *SEL; //===------------------------------------------------------------------------=== // Don't warn about iVars that are IBOutlets. -#ifndef IBOutlet -#define IBOutlet -#endif - @class NSWindow; @interface HasOutlet : NSObject { diff --git a/test/Analysis/NoReturn.m b/test/Analysis/NoReturn.m index ea2efd061711..1d948fa66f6d 100644 --- a/test/Analysis/NoReturn.m +++ b/test/Analysis/NoReturn.m @@ -76,3 +76,15 @@ int f3(int* x) { return *x; // no-warning } + +@interface CustomException : NSException +@end + +int testCustomException(int *x) { + if (x != 0) return 0; + + [CustomException raise:@"Blah" format:@"abc"]; + + return *x; // no-warning +} + diff --git a/test/Analysis/PR12905.c b/test/Analysis/PR12905.c new file mode 100644 index 000000000000..8f678d114472 --- /dev/null +++ b/test/Analysis/PR12905.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core %s +// PR12905 + +void C(void); + +void t(void) { + C(); +} diff --git a/test/Analysis/additive-folding-range-constraints.c b/test/Analysis/additive-folding-range-constraints.c index 32e0cfe142ad..7eb55ab1e125 100644 --- a/test/Analysis/additive-folding-range-constraints.c +++ b/test/Analysis/additive-folding-range-constraints.c @@ -1,53 +1,37 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -verify -analyzer-constraints=range %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -analyzer-constraints=range %s + +void clang_analyzer_eval(int); + +#define UINT_MAX (~0U) +#define INT_MAX (UINT_MAX & (UINT_MAX >> 1)) +#define INT_MIN (-INT_MAX - 1) -// 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 (__INT_MAX__ *2U +1U) // Each of these adjusted ranges has an adjustment small enough to split the // solution range across an overflow boundary (Min for <, Max for >). // This corresponds to one set of branches in RangeConstraintManager. void smallAdjustmentGT (unsigned a) { - char* 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) { - char* 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) { - char* 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) { - char* 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}} } @@ -55,45 +39,134 @@ 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) { - char* 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) { - char* 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) { - char* 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) { - char* 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; + + clang_analyzer_eval((a - 2) >= (min + 5LL)); // 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 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)) { + 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. + 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) { + 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 5: The range is inside and may or may not wrap. + clang_analyzer_eval((a + 5) == 0LL); // expected-warning{{UNKNOWN}} + + 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 { + 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) { + 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 mixedComparisons7(signed char a) { + // Case 7: The range wraps around but is entirely outside the symbol's range. + int min = INT_MIN; + + clang_analyzer_eval((a + 2) >= (min + 5LL)); // 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 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) { + 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 mixedComparisons9(signed char a) { + // Case 9: The range is entirely above the symbol's range. + int max = INT_MAX; + + clang_analyzer_eval((a + 2) <= (max - 5LL)); // 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}} } diff --git a/test/Analysis/additive-folding.c b/test/Analysis/additive-folding.c deleted file mode 100644 index beb08aa59c2f..000000000000 --- a/test/Analysis/additive-folding.c +++ /dev/null @@ -1,203 +0,0 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,unix.Malloc -verify -analyzer-constraints=basic %s -// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,unix.Malloc -verify -analyzer-constraints=range %s - -// These are used to trigger warnings. -typedef typeof(sizeof(int)) size_t; -void *malloc(size_t); -void free(void *); -#define NULL ((void*)0) -#define UINT_MAX -1U - -//--------------- -// Plus/minus -//--------------- - -void separateExpressions (int a) { - int b = a + 1; - --b; - - char* buf = malloc(1); - if (a != 0 && b == 0) - return; // expected-warning{{never executed}} - free(buf); -} - -void oneLongExpression (int a) { - // Expression canonicalization should still allow this to work, even though - // the first term is on the left. - int b = 15 + a + 15 - 10 - 20; - - char* buf = malloc(1); - if (a != 0 && b == 0) - return; // expected-warning{{never executed}} - free(buf); -} - -void mixedTypes (int a) { - char* buf = malloc(1); - - // Different additive types should not cause crashes when constant-folding. - // This is part of PR7406. - int b = a + 1LL; - if (a != 0 && (b-1) == 0) // not crash - return; // expected-warning{{never executed}} - - int c = a + 1U; - if (a != 0 && (c-1) == 0) // not crash - return; // expected-warning{{never executed}} - - free(buf); -} - -//--------------- -// Comparisons -//--------------- - -// Equality and inequality only -void eq_ne (unsigned a) { - char* b = NULL; - if (a == UINT_MAX) - b = malloc(1); - if (a+1 != 0) - return; // no-warning - if (a-1 != UINT_MAX-1) - return; // no-warning - free(b); -} - -void ne_eq (unsigned a) { - char* b = NULL; - if (a != UINT_MAX) - b = malloc(1); - if (a+1 == 0) - return; // no-warning - if (a-1 == UINT_MAX-1) - return; // no-warning - free(b); -} - -// Mixed typed inequalities (part of PR7406) -// These should not crash. -void mixed_eq_ne (int a) { - char* b = NULL; - if (a == 1) - b = malloc(1); - if (a+1U != 2) - return; // no-warning - if (a-1U != 0) - return; // expected-warning{{never executed}} - free(b); -} - -void mixed_ne_eq (int a) { - char* b = NULL; - if (a != 1) - b = malloc(1); - if (a+1U == 2) - return; // no-warning - if (a-1U == 0) - return; // expected-warning{{never executed}} - free(b); -} - - -// Simple order comparisons with no adjustment -void baselineGT (unsigned a) { - char* b = NULL; - if (a > 0) - b = malloc(1); - if (a == 0) - return; // no-warning - free(b); -} - -void baselineGE (unsigned a) { - char* b = NULL; - if (a >= UINT_MAX) - b = malloc(1); - if (a == UINT_MAX) - free(b); - return; // no-warning -} - -void baselineLT (unsigned a) { - char* b = NULL; - if (a < UINT_MAX) - b = malloc(1); - if (a == UINT_MAX) - return; // no-warning - free(b); -} - -void baselineLE (unsigned a) { - char* b = NULL; - if (a <= 0) - b = malloc(1); - if (a == 0) - free(b); - return; // no-warning -} - - -// Adjustment gives each of these an extra solution! -void adjustedGT (unsigned a) { - char* b = NULL; - if (a-1 > UINT_MAX-1) - b = malloc(1); - return; // expected-warning{{leak}} -} - -void adjustedGE (unsigned a) { - char* b = NULL; - if (a-1 >= UINT_MAX-1) - b = malloc(1); - if (a == UINT_MAX) - free(b); - return; // expected-warning{{leak}} -} - -void adjustedLT (unsigned a) { - char* b = NULL; - if (a+1 < 1) - b = malloc(1); - return; // expected-warning{{leak}} -} - -void adjustedLE (unsigned a) { - char* b = NULL; - if (a+1 <= 1) - b = malloc(1); - if (a == 0) - free(b); - return; // expected-warning{{leak}} -} - - -// Tautologies -void tautologyGT (unsigned a) { - char* b = malloc(1); - if (a > UINT_MAX) - return; // no-warning - free(b); -} - -void tautologyGE (unsigned a) { - char* b = malloc(1); - if (a >= 0) // expected-warning{{always true}} - free(b); - return; // no-warning -} - -void tautologyLT (unsigned a) { - char* b = malloc(1); - if (a < 0) // expected-warning{{always false}} - return; // expected-warning{{never executed}} - free(b); -} - -void tautologyLE (unsigned a) { - char* b = malloc(1); - if (a <= UINT_MAX) - free(b); - return; // no-warning -} diff --git a/test/Analysis/additive-folding.cpp b/test/Analysis/additive-folding.cpp new file mode 100644 index 000000000000..0d749ec3cbaf --- /dev/null +++ b/test/Analysis/additive-folding.cpp @@ -0,0 +1,196 @@ +// 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) + +//--------------- +// Plus/minus +//--------------- + +void separateExpressions (int a) { + int b = a + 1; + --b; + + clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}} +} + +void oneLongExpression (int a) { + // Expression canonicalization should still allow this to work, even though + // the first term is on the left. + int b = 15 + a + 15 - 10 - 20; + + clang_analyzer_eval(a != 0 && b == 0); // expected-warning{{FALSE}} +} + +void mixedTypes (int a) { + // Different additive types should not cause crashes when constant-folding. + // This is part of PR7406. + int b = a + 1LL; + clang_analyzer_eval(a != 0 && (b-1) == 0); // not crash, expected-warning{{FALSE}} + + int c = a + 1U; + clang_analyzer_eval(a != 0 && (c-1) == 0); // not crash, expected-warning{{FALSE}} +} + +//--------------- +// Comparisons +//--------------- + +// Equality and inequality only +void eq_ne (unsigned a) { + 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) { + 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) { + if (a > 0) + clang_analyzer_eval(a != 0); // expected-warning{{TRUE}} + else + clang_analyzer_eval(a == 0); // expected-warning{{TRUE}} +} + +void baselineGE (unsigned a) { + if (a >= UINT_MAX) + clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}} + else + clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}} +} + +void baselineLT (unsigned a) { + if (a < UINT_MAX) + clang_analyzer_eval(a != UINT_MAX); // expected-warning{{TRUE}} + else + clang_analyzer_eval(a == UINT_MAX); // expected-warning{{TRUE}} +} + +void baselineLE (unsigned a) { + if (a <= 0) + 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) { + clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}} +} + +void adjustedGE (unsigned a) { + clang_analyzer_eval(a-1 > UINT_MAX-1); // expected-warning{{UNKNOWN}} + + if (a-1 >= UINT_MAX-1) + clang_analyzer_eval(a == UINT_MAX); // expected-warning{{UNKNOWN}} +} + +void adjustedLT (unsigned a) { + clang_analyzer_eval(a+1 < 1); // expected-warning{{UNKNOWN}} +} + +void adjustedLE (unsigned a) { + clang_analyzer_eval(a+1 <= 1); // expected-warning{{UNKNOWN}} + + if (a+1 <= 1) + clang_analyzer_eval(a == 0); // expected-warning{{UNKNOWN}} +} + + +// Tautologies +// 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 tautologiesOutside(unsigned char a) { + clang_analyzer_eval(a <= 0x100); // expected-warning{{TRUE}} + clang_analyzer_eval(a < 0x100); // expected-warning{{TRUE}} + + clang_analyzer_eval(a != 0x100); // expected-warning{{TRUE}} + clang_analyzer_eval(a != -1); // expected-warning{{TRUE}} + + clang_analyzer_eval(a > -1); // expected-warning{{TRUE}} + clang_analyzer_eval(a >= -1); // expected-warning{{TRUE}} +} + + +// Wraparound with mixed types. Note that the analyzer assumes +// -fwrapv semantics. +void mixedWraparoundSanityCheck(int a) { + int max = INT_MAX; + int min = INT_MIN; + + int b = a + 1; + clang_analyzer_eval(a == max && b != min); // expected-warning{{FALSE}} +} + +void mixedWraparoundLE_GT(int a) { + int max = INT_MAX; + int min = INT_MIN; + + 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 mixedWraparoundGE_LT(int a) { + int max = INT_MAX; + int min = INT_MIN; + + 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_NE(int a) { + int max = INT_MAX; + + clang_analyzer_eval((a + 2) != (max + 1LL)); // expected-warning{{TRUE}} + clang_analyzer_eval((a + 2LL) == (max + 1LL)); // expected-warning{{UNKNOWN}} +} + + +// Mixed-signedness comparisons. +void mixedSignedness(int a, unsigned b) { + int sMin = INT_MIN; + unsigned uMin = INT_MIN; + + clang_analyzer_eval(a == sMin && a != uMin); // expected-warning{{FALSE}} + clang_analyzer_eval(b == uMin && b != sMin); // expected-warning{{FALSE}} +} + + +void multiplicativeSanityTest(int x) { + // At one point we were ignoring the *4 completely -- the constraint manager + // would see x < 8 and then declare the assertion to be known false. + if (x*4 < 8) + return; + + 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 4b085c8d7002..244bc977b511 100644 --- a/test/Analysis/array-struct-region.c +++ b/test/Analysis/array-struct-region.c @@ -1,32 +1,28 @@ -// 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 -analyzer-ipa=inlining -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -analyzer-ipa=inlining -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; } void nested_compound_literals(int rad) { - int vec[6][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, // expected-warning 6 {{implicit conversion turns literal floating-point number into integer}} - {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; // expected-warning 6 {{implicit conversion turns literal floating-point number into integer}} + int vec[6][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, // expected-warning 6 {{implicit conversion from 'double' to 'int' changes value from}} + {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; // expected-warning 6 {{implicit conversion from 'double' to 'int' changes value from}} int a; for (a = 0; a < 6; ++a) { @@ -45,3 +41,146 @@ void nested_compound_literals_float(float rad) { vec[a][1] *= rad; // no-warning } } + + +void struct_as_array() { + struct simple { int x; int y; }; + struct simple a; + struct simple *p = &a; + + p->x = 5; + 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}} +} + + +// PR13264 / <rdar://problem/11802440> +struct point { int x; int y; }; +struct circle { struct point o; int r; }; +struct circle get_circle() { + struct circle result; + result.r = 5; + result.o = (struct point){0, 0}; + return result; +} + +void struct_in_struct() { + struct circle c; + c = get_circle(); + // This used to think c.r was undefined because c.o is a LazyCompoundVal. + clang_analyzer_eval(c.r == 5); // expected-warning{{TRUE}} +} + +// We also test with floats because we don't model floats right now, +// and the original bug report used a float. +struct circle_f { struct point o; float r; }; +struct circle_f get_circle_f() { + struct circle_f result; + result.r = 5.0; + result.o = (struct point){0, 0}; + return result; +} + +float struct_in_struct_f() { + struct circle_f c; + c = get_circle_f(); + + return c.r; // no-warning +} + + +int randomInt(); + +int testSymbolicInvalidation(int index) { + int vals[10]; + + vals[0] = 42; + clang_analyzer_eval(vals[0] == 42); // expected-warning{{TRUE}} + + vals[index] = randomInt(); + clang_analyzer_eval(vals[0] == 42); // expected-warning{{UNKNOWN}} + + return vals[index]; // no-warning +} + +int testConcreteInvalidation(int index) { + int vals[10]; + + vals[index] = 42; + clang_analyzer_eval(vals[index] == 42); // expected-warning{{TRUE}} + vals[0] = randomInt(); + clang_analyzer_eval(vals[index] == 42); // expected-warning{{UNKNOWN}} + + return vals[0]; // no-warning +} + + +typedef struct { + int x, y, z; +} S; + +S makeS(); + +int testSymbolicInvalidationStruct(int index) { + S vals[10]; + + vals[0].x = 42; + clang_analyzer_eval(vals[0].x == 42); // expected-warning{{TRUE}} + + vals[index] = makeS(); + clang_analyzer_eval(vals[0].x == 42); // expected-warning{{UNKNOWN}} + + return vals[index].x; // no-warning +} + +int testConcreteInvalidationStruct(int index) { + S vals[10]; + + vals[index].x = 42; + clang_analyzer_eval(vals[index].x == 42); // expected-warning{{TRUE}} + vals[0] = makeS(); + clang_analyzer_eval(vals[index].x == 42); // expected-warning{{UNKNOWN}} + + return vals[0].x; // no-warning +} + +typedef struct { + S a[5]; + S b[5]; +} SS; + +int testSymbolicInvalidationDoubleStruct(int index) { + SS vals; + + vals.a[0].x = 42; + vals.b[0].x = 42; + clang_analyzer_eval(vals.a[0].x == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(vals.b[0].x == 42); // expected-warning{{TRUE}} + + vals.a[index] = makeS(); + clang_analyzer_eval(vals.a[0].x == 42); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(vals.b[0].x == 42); // expected-warning{{TRUE}} + + return vals.b[index].x; // no-warning +} + +int testConcreteInvalidationDoubleStruct(int index) { + SS vals; + + vals.a[index].x = 42; + vals.b[index].x = 42; + clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(vals.b[index].x == 42); // expected-warning{{TRUE}} + + vals.a[0] = makeS(); + clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(vals.b[index].x == 42); // expected-warning{{TRUE}} + + return vals.b[0].x; // no-warning +} + + diff --git a/test/Analysis/auto-obj-dtors-cfg-output.cpp b/test/Analysis/auto-obj-dtors-cfg-output.cpp index 67a8f2e555bd..566e6caed60d 100644 --- a/test/Analysis/auto-obj-dtors-cfg-output.cpp +++ b/test/Analysis/auto-obj-dtors-cfg-output.cpp @@ -416,121 +416,121 @@ void test_catch_copy() { // CHECK: [B6 (ENTRY)] // CHECK: Succs (1): B5 // CHECK: [B1] -// CHECK: 1: [B2.4].~A() (Implicit destructor) +// CHECK: 1: [B4.4].~A() (Implicit destructor) // CHECK: 2: [B5.2].~A() (Implicit destructor) -// CHECK: Preds (1): B2 +// CHECK: Preds (1): B4 // CHECK: Succs (1): B0 // CHECK: [B2] -// CHECK: 1: a -// CHECK: 2: [B2.1] (ImplicitCastExpr, NoOp, const class A) -// CHECK: 3: [B2.2] (CXXConstructExpr, class A) -// CHECK: 4: A b = a; -// CHECK: 5: b -// CHECK: 6: [B2.5] (ImplicitCastExpr, NoOp, const class A) -// CHECK: 7: [B2.6].operator int -// CHECK: 8: [B2.7]() -// CHECK: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, int) -// CHECK: 10: [B2.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) -// CHECK: T: while [B2.10] -// CHECK: Preds (2): B3 B5 -// CHECK: Succs (2): B4 B1 +// CHECK: Preds (1): B3 +// CHECK: Succs (1): B4 // CHECK: [B3] +// CHECK: 1: (CXXConstructExpr, class A) +// CHECK: 2: A c; +// CHECK: 3: [B3.2].~A() (Implicit destructor) +// CHECK: 4: [B4.4].~A() (Implicit destructor) // CHECK: Preds (1): B4 // CHECK: Succs (1): B2 // CHECK: [B4] -// CHECK: 1: (CXXConstructExpr, class A) -// CHECK: 2: A c; -// CHECK: 3: [B4.2].~A() (Implicit destructor) -// CHECK: 4: [B2.4].~A() (Implicit destructor) -// CHECK: Preds (1): B2 -// CHECK: Succs (1): B3 +// CHECK: 1: a +// CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) +// CHECK: 3: [B4.2] (CXXConstructExpr, class A) +// CHECK: 4: A b = a; +// CHECK: 5: b +// CHECK: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) +// CHECK: 7: [B4.6].operator int +// CHECK: 8: [B4.7]() +// CHECK: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, int) +// CHECK: 10: [B4.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) +// CHECK: T: while [B4.10] +// CHECK: Preds (2): B2 B5 +// CHECK: Succs (2): B3 B1 // CHECK: [B5] // CHECK: 1: (CXXConstructExpr, class A) // CHECK: 2: A a; // CHECK: Preds (1): B6 -// CHECK: Succs (1): B2 +// CHECK: Succs (1): B4 // CHECK: [B0 (EXIT)] // CHECK: Preds (1): B1 // CHECK: [B12 (ENTRY)] // CHECK: Succs (1): B11 // CHECK: [B1] -// CHECK: 1: [B2.4].~A() (Implicit destructor) +// CHECK: 1: [B10.4].~A() (Implicit destructor) // CHECK: 2: (CXXConstructExpr, class A) // CHECK: 3: A e; // CHECK: 4: [B1.3].~A() (Implicit destructor) // CHECK: 5: [B11.2].~A() (Implicit destructor) -// CHECK: Preds (2): B9 B2 +// CHECK: Preds (2): B8 B10 // CHECK: Succs (1): B0 // CHECK: [B2] -// CHECK: 1: a -// CHECK: 2: [B2.1] (ImplicitCastExpr, NoOp, const class A) -// CHECK: 3: [B2.2] (CXXConstructExpr, class A) -// CHECK: 4: A b = a; -// CHECK: 5: b -// CHECK: 6: [B2.5] (ImplicitCastExpr, NoOp, const class A) -// CHECK: 7: [B2.6].operator int -// CHECK: 8: [B2.7]() -// CHECK: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, int) -// CHECK: 10: [B2.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) -// CHECK: T: while [B2.10] -// CHECK: Preds (2): B3 B11 -// CHECK: Succs (2): B10 B1 +// CHECK: Preds (2): B3 B6 +// CHECK: Succs (1): B10 // CHECK: [B3] -// CHECK: Preds (2): B4 B7 -// CHECK: Succs (1): B2 -// CHECK: [B4] // CHECK: 1: (CXXConstructExpr, class A) // CHECK: 2: A d; -// CHECK: 3: [B4.2].~A() (Implicit destructor) -// CHECK: 4: [B10.2].~A() (Implicit destructor) -// CHECK: 5: [B2.4].~A() (Implicit destructor) -// CHECK: Preds (1): B6 -// CHECK: Succs (1): B3 -// CHECK: [B5] +// CHECK: 3: [B3.2].~A() (Implicit destructor) +// CHECK: 4: [B9.2].~A() (Implicit destructor) +// CHECK: 5: [B10.4].~A() (Implicit destructor) +// CHECK: Preds (1): B5 +// CHECK: Succs (1): B2 +// CHECK: [B4] // CHECK: 1: return; -// CHECK: 2: [B10.2].~A() (Implicit destructor) -// CHECK: 3: [B2.4].~A() (Implicit destructor) +// CHECK: 2: [B9.2].~A() (Implicit destructor) +// CHECK: 3: [B10.4].~A() (Implicit destructor) // CHECK: 4: [B11.2].~A() (Implicit destructor) -// CHECK: Preds (1): B6 +// CHECK: Preds (1): B5 // CHECK: Succs (1): B0 -// CHECK: [B6] +// CHECK: [B5] // CHECK: 1: UV -// CHECK: 2: [B6.1] (ImplicitCastExpr, LValueToRValue, _Bool) -// CHECK: T: if [B6.2] -// CHECK: Preds (1): B8 -// CHECK: Succs (2): B5 B4 -// CHECK: [B7] -// CHECK: 1: [B10.2].~A() (Implicit destructor) -// CHECK: 2: [B2.4].~A() (Implicit destructor) +// CHECK: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) +// CHECK: T: if [B5.2] +// CHECK: Preds (1): B7 +// CHECK: Succs (2): B4 B3 +// CHECK: [B6] +// CHECK: 1: [B9.2].~A() (Implicit destructor) +// CHECK: 2: [B10.4].~A() (Implicit destructor) // CHECK: T: continue; -// CHECK: Preds (1): B8 -// CHECK: Succs (1): B3 -// CHECK: [B8] +// CHECK: Preds (1): B7 +// CHECK: Succs (1): B2 +// CHECK: [B7] // CHECK: 1: UV -// CHECK: 2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool) -// CHECK: T: if [B8.2] -// CHECK: Preds (1): B10 -// CHECK: Succs (2): B7 B6 -// CHECK: [B9] -// CHECK: 1: [B10.2].~A() (Implicit destructor) +// CHECK: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) +// CHECK: T: if [B7.2] +// CHECK: Preds (1): B9 +// CHECK: Succs (2): B6 B5 +// CHECK: [B8] +// CHECK: 1: [B9.2].~A() (Implicit destructor) // CHECK: T: break; -// CHECK: Preds (1): B10 +// CHECK: Preds (1): B9 // CHECK: Succs (1): B1 -// CHECK: [B10] +// CHECK: [B9] // CHECK: 1: (CXXConstructExpr, class A) // CHECK: 2: A c; // CHECK: 3: UV -// CHECK: 4: [B10.3] (ImplicitCastExpr, LValueToRValue, _Bool) -// CHECK: T: if [B10.4] -// CHECK: Preds (1): B2 -// CHECK: Succs (2): B9 B8 +// CHECK: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) +// CHECK: T: if [B9.4] +// CHECK: Preds (1): B10 +// CHECK: Succs (2): B8 B7 +// CHECK: [B10] +// CHECK: 1: a +// CHECK: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A) +// CHECK: 3: [B10.2] (CXXConstructExpr, class A) +// CHECK: 4: A b = a; +// CHECK: 5: b +// CHECK: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) +// CHECK: 7: [B10.6].operator int +// CHECK: 8: [B10.7]() +// CHECK: 9: [B10.8] (ImplicitCastExpr, UserDefinedConversion, int) +// CHECK: 10: [B10.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) +// CHECK: T: while [B10.10] +// CHECK: Preds (2): B2 B11 +// CHECK: Succs (2): B9 B1 // CHECK: [B11] // CHECK: 1: (CXXConstructExpr, class A) // CHECK: 2: A a; // CHECK: Preds (1): B12 -// CHECK: Succs (1): B2 +// CHECK: Succs (1): B10 // CHECK: [B0 (EXIT)] -// CHECK: Preds (2): B1 B5 +// CHECK: Preds (2): B1 B4 // CHECK: [B4 (ENTRY)] // CHECK: Succs (1): B2 // CHECK: [B1] @@ -717,124 +717,124 @@ void test_catch_copy() { // CHECK: [B6 (ENTRY)] // CHECK: Succs (1): B5 // CHECK: [B1] -// CHECK: 1: [B2.4].~A() (Implicit destructor) +// CHECK: 1: [B4.4].~A() (Implicit destructor) // CHECK: 2: [B5.2].~A() (Implicit destructor) -// CHECK: Preds (1): B2 +// CHECK: Preds (1): B4 // CHECK: Succs (1): B0 // CHECK: [B2] -// CHECK: 1: a -// CHECK: 2: [B2.1] (ImplicitCastExpr, NoOp, const class A) -// CHECK: 3: [B2.2] (CXXConstructExpr, class A) -// CHECK: 4: A b = a; -// CHECK: 5: b -// CHECK: 6: [B2.5] (ImplicitCastExpr, NoOp, const class A) -// CHECK: 7: [B2.6].operator int -// CHECK: 8: [B2.7]() -// CHECK: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, int) -// CHECK: 10: [B2.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) -// CHECK: T: for (...; [B2.10]; ) -// CHECK: Preds (2): B3 B5 -// CHECK: Succs (2): B4 B1 +// CHECK: Preds (1): B3 +// CHECK: Succs (1): B4 // CHECK: [B3] -// CHECK: 1: [B2.4].~A() (Implicit destructor) +// CHECK: 1: (CXXConstructExpr, class A) +// CHECK: 2: A c; +// CHECK: 3: [B3.2].~A() (Implicit destructor) +// CHECK: 4: [B4.4].~A() (Implicit destructor) // CHECK: Preds (1): B4 // CHECK: Succs (1): B2 // CHECK: [B4] -// CHECK: 1: (CXXConstructExpr, class A) -// CHECK: 2: A c; -// CHECK: 3: [B4.2].~A() (Implicit destructor) -// CHECK: Preds (1): B2 -// CHECK: Succs (1): B3 +// CHECK: 1: a +// CHECK: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) +// CHECK: 3: [B4.2] (CXXConstructExpr, class A) +// CHECK: 4: A b = a; +// CHECK: 5: b +// CHECK: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) +// CHECK: 7: [B4.6].operator int +// CHECK: 8: [B4.7]() +// CHECK: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, int) +// CHECK: 10: [B4.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) +// CHECK: T: for (...; [B4.10]; ) +// CHECK: Preds (2): B2 B5 +// CHECK: Succs (2): B3 B1 // CHECK: [B5] // CHECK: 1: (CXXConstructExpr, class A) // CHECK: 2: A a; // CHECK: Preds (1): B6 -// CHECK: Succs (1): B2 +// CHECK: Succs (1): B4 // CHECK: [B0 (EXIT)] // CHECK: Preds (1): B1 // CHECK: [B12 (ENTRY)] // CHECK: Succs (1): B11 // CHECK: [B1] -// CHECK: 1: [B2.4].~A() (Implicit destructor) +// CHECK: 1: [B10.4].~A() (Implicit destructor) // CHECK: 2: [B11.4].~A() (Implicit destructor) // CHECK: 3: (CXXConstructExpr, class A) // CHECK: 4: A f; // CHECK: 5: [B1.4].~A() (Implicit destructor) // CHECK: 6: [B11.2].~A() (Implicit destructor) -// CHECK: Preds (2): B9 B2 +// CHECK: Preds (2): B8 B10 // CHECK: Succs (1): B0 // CHECK: [B2] -// CHECK: 1: b -// CHECK: 2: [B2.1] (ImplicitCastExpr, NoOp, const class A) -// CHECK: 3: [B2.2] (CXXConstructExpr, class A) -// CHECK: 4: A c = b; -// CHECK: 5: c -// CHECK: 6: [B2.5] (ImplicitCastExpr, NoOp, const class A) -// CHECK: 7: [B2.6].operator int -// CHECK: 8: [B2.7]() -// CHECK: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, int) -// CHECK: 10: [B2.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) -// CHECK: T: for (...; [B2.10]; ) -// CHECK: Preds (2): B3 B11 -// CHECK: Succs (2): B10 B1 +// CHECK: Preds (2): B3 B6 +// CHECK: Succs (1): B10 // CHECK: [B3] -// CHECK: 1: [B2.4].~A() (Implicit destructor) -// CHECK: Preds (2): B4 B7 -// CHECK: Succs (1): B2 -// CHECK: [B4] // CHECK: 1: (CXXConstructExpr, class A) // CHECK: 2: A e; -// CHECK: 3: [B4.2].~A() (Implicit destructor) -// CHECK: 4: [B10.2].~A() (Implicit destructor) -// CHECK: Preds (1): B6 -// CHECK: Succs (1): B3 -// CHECK: [B5] +// CHECK: 3: [B3.2].~A() (Implicit destructor) +// CHECK: 4: [B9.2].~A() (Implicit destructor) +// CHECK: 5: [B10.4].~A() (Implicit destructor) +// CHECK: Preds (1): B5 +// CHECK: Succs (1): B2 +// CHECK: [B4] // CHECK: 1: return; -// CHECK: 2: [B10.2].~A() (Implicit destructor) -// CHECK: 3: [B2.4].~A() (Implicit destructor) +// CHECK: 2: [B9.2].~A() (Implicit destructor) +// CHECK: 3: [B10.4].~A() (Implicit destructor) // CHECK: 4: [B11.4].~A() (Implicit destructor) // CHECK: 5: [B11.2].~A() (Implicit destructor) -// CHECK: Preds (1): B6 +// CHECK: Preds (1): B5 // CHECK: Succs (1): B0 -// CHECK: [B6] +// CHECK: [B5] // CHECK: 1: UV -// CHECK: 2: [B6.1] (ImplicitCastExpr, LValueToRValue, _Bool) -// CHECK: T: if [B6.2] -// CHECK: Preds (1): B8 -// CHECK: Succs (2): B5 B4 -// CHECK: [B7] -// CHECK: 1: [B10.2].~A() (Implicit destructor) +// CHECK: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, _Bool) +// CHECK: T: if [B5.2] +// CHECK: Preds (1): B7 +// CHECK: Succs (2): B4 B3 +// CHECK: [B6] +// CHECK: 1: [B9.2].~A() (Implicit destructor) // CHECK: T: continue; -// CHECK: Preds (1): B8 -// CHECK: Succs (1): B3 -// CHECK: [B8] +// CHECK: Preds (1): B7 +// CHECK: Succs (1): B2 +// CHECK: [B7] // CHECK: 1: UV -// CHECK: 2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool) -// CHECK: T: if [B8.2] -// CHECK: Preds (1): B10 -// CHECK: Succs (2): B7 B6 -// CHECK: [B9] -// CHECK: 1: [B10.2].~A() (Implicit destructor) +// CHECK: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool) +// CHECK: T: if [B7.2] +// CHECK: Preds (1): B9 +// CHECK: Succs (2): B6 B5 +// CHECK: [B8] +// CHECK: 1: [B9.2].~A() (Implicit destructor) // CHECK: T: break; -// CHECK: Preds (1): B10 +// CHECK: Preds (1): B9 // CHECK: Succs (1): B1 -// CHECK: [B10] +// CHECK: [B9] // CHECK: 1: (CXXConstructExpr, class A) // CHECK: 2: A d; // CHECK: 3: UV -// CHECK: 4: [B10.3] (ImplicitCastExpr, LValueToRValue, _Bool) -// CHECK: T: if [B10.4] -// CHECK: Preds (1): B2 -// CHECK: Succs (2): B9 B8 +// CHECK: 4: [B9.3] (ImplicitCastExpr, LValueToRValue, _Bool) +// CHECK: T: if [B9.4] +// CHECK: Preds (1): B10 +// CHECK: Succs (2): B8 B7 +// CHECK: [B10] +// CHECK: 1: b +// CHECK: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A) +// CHECK: 3: [B10.2] (CXXConstructExpr, class A) +// CHECK: 4: A c = b; +// CHECK: 5: c +// CHECK: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) +// CHECK: 7: [B10.6].operator int +// CHECK: 8: [B10.7]() +// CHECK: 9: [B10.8] (ImplicitCastExpr, UserDefinedConversion, int) +// CHECK: 10: [B10.9] (ImplicitCastExpr, IntegralToBoolean, _Bool) +// CHECK: T: for (...; [B10.10]; ) +// CHECK: Preds (2): B2 B11 +// CHECK: Succs (2): B9 B1 // CHECK: [B11] // CHECK: 1: (CXXConstructExpr, class A) // CHECK: 2: A a; // CHECK: 3: (CXXConstructExpr, class A) // CHECK: 4: A b; // CHECK: Preds (1): B12 -// CHECK: Succs (1): B2 +// CHECK: Succs (1): B10 // CHECK: [B0 (EXIT)] -// CHECK: Preds (2): B1 B5 +// CHECK: Preds (2): B1 B4 // CHECK: [B3 (ENTRY)] // CHECK: Succs (1): B0 // CHECK: [B1] @@ -862,3 +862,4 @@ void test_catch_copy() { // CHECK: Succs (1): B0 // CHECK: [B0 (EXIT)] // CHECK: Preds (3): B2 B1 B3 + diff --git a/test/Analysis/base-init.cpp b/test/Analysis/base-init.cpp index 8fd7abcc3778..e63d50855e10 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 -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/blocks-no-inline.c b/test/Analysis/blocks-no-inline.c new file mode 100644 index 000000000000..1ec14e820b0e --- /dev/null +++ b/test/Analysis/blocks-no-inline.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=none -fblocks -verify %s + +void clang_analyzer_eval(int); + +void testInvalidation() { + __block int i = 0; + ^{ + ++i; + }(); + + // Under inlining, we will know that i == 1. + clang_analyzer_eval(i == 0); // expected-warning{{UNKNOWN}} +} diff --git a/test/Analysis/blocks.m b/test/Analysis/blocks.m index 7a604ddb4d91..ff376d17a1a1 100644 --- a/test/Analysis/blocks.m +++ b/test/Analysis/blocks.m @@ -79,9 +79,7 @@ void test2() { void test2_b() { static int y = 0; __block int x; - // This is also a bug, but should be found not by checking the value - // 'x' is bound at block creation. - ^{ y = x + 1; }(); // no-warning + ^{ y = x + 1; }(); // expected-warning {{left operand of '+' is a garbage value}} } void test2_c() { diff --git a/test/Analysis/bstring.c b/test/Analysis/bstring.c index 833c917613ed..d383d421d444 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, 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 () { @@ -428,3 +425,13 @@ void bcopy2 () { bcopy(src, dst, 4); // expected-warning{{overflow}} } + +void *malloc(size_t); +void free(void *); +char radar_11125445_memcopythenlogfirstbyte(const char *input, size_t length) { + char *bytes = malloc(sizeof(char) * (length + 1)); + memcpy(bytes, input, length); + char x = bytes[0]; // no warning + free(bytes); + return x; +} diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c index 8b88a2db432e..f862ddf57315 100644 --- a/test/Analysis/casts.c +++ b/test/Analysis/casts.c @@ -65,3 +65,11 @@ void pr6013_6035_test(void *p) { foo = ((long)(p)); (void) foo; } + +// PR12511 and radar://11215362 - Test that we support SymCastExpr, which represents symbolic int to float cast. +char ttt(int intSeconds) { + double seconds = intSeconds; + if (seconds) + return 0; + return 0; +} diff --git a/test/Analysis/comparison-implicit-casts.cpp b/test/Analysis/comparison-implicit-casts.cpp new file mode 100644 index 000000000000..df9d8700099e --- /dev/null +++ b/test/Analysis/comparison-implicit-casts.cpp @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-constraints=basic -triple i386-apple-darwin9 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-constraints=basic -triple x86_64-apple-darwin9 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-constraints=range -triple i386-apple-darwin9 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-constraints=range -triple x86_64-apple-darwin9 -verify %s + +// This file runs in C++ mode so that the comparison type is 'bool', not 'int'. +void clang_analyzer_eval(int); +typedef typeof(sizeof(int)) size_t; + +// PR12206/12510 - When SimpleSValBuilder figures out that a symbol is fully +// constrained, it should cast the value to the result type in a binary +// operation...unless the binary operation is a comparison, in which case the +// two arguments should be the same type, but won't match the result type. +// +// This is not directly related to additive folding, but we use SValBuilder's +// additive folding to tickle the bug. ExprEngine will simplify fully-constrained +// symbols, so SValBuilder will only see them if they are (a) part of an evaluated +// SymExpr (e.g. with additive folding) or (b) generated by a checker (e.g. +// unix.cstring's strlen() modelling). +void PR12206(int x) { + size_t comparisonSize = sizeof(1 == 1); + + // Sanity check. This test is useless if size_t isn't bigger than bool. + clang_analyzer_eval(sizeof(size_t) > comparisonSize); // expected-warning{{TRUE}} + + // Build a SymIntExpr, dependent on x. + int local = x - 1; + + // Create a value that requires more bits to store than a comparison result. + int value = 1; + value <<= 8 * comparisonSize; + value += 1; + + // Constrain the value of x. + if (x != value) return; + + // Constant-folding will turn (local+1) back into the symbol for x. + // The point of this dance is to make SValBuilder be responsible for + // turning the symbol into a ConcreteInt, rather than ExprEngine. + + // Test relational operators. + clang_analyzer_eval((local + 1) >= 2); // expected-warning{{TRUE}} + clang_analyzer_eval(2 <= (local + 1)); // expected-warning{{TRUE}} + + // Test equality operators. + clang_analyzer_eval((local + 1) != 1); // expected-warning{{TRUE}} + clang_analyzer_eval(1 != (local + 1)); // expected-warning{{TRUE}} +} + +void PR12206_truncation(signed char x) { + // Build a SymIntExpr, dependent on x. + signed char local = x - 1; + + // Constrain the value of x. + if (x != 1) return; + + // Constant-folding will turn (local+1) back into the symbol for x. + // The point of this dance is to make SValBuilder be responsible for + // turning the symbol into a ConcreteInt, rather than ExprEngine. + + // Construct a value that cannot be represented by 'char', + // but that has the same lower bits as x. + signed int value = 1 + (1 << 8); + + // Test relational operators. + clang_analyzer_eval((local + 1) < value); // expected-warning{{TRUE}} + clang_analyzer_eval(value > (local + 1)); // expected-warning{{TRUE}} + + // Test equality operators. + clang_analyzer_eval((local + 1) != value); // expected-warning{{TRUE}} + clang_analyzer_eval(value != (local + 1)); // expected-warning{{TRUE}} +} + +// This test is insurance in case we significantly change how SymExprs are +// evaluated. +size_t strlen(const char *s); +void PR12206_strlen(const char *x) { + size_t comparisonSize = sizeof(1 == 1); + + // Sanity check. This test is useless if size_t isn't bigger than bool. + clang_analyzer_eval(sizeof(size_t) > comparisonSize); // expected-warning{{TRUE}} + + // Create a value that requires more bits to store than a comparison result. + size_t value = 1UL; + value <<= 8 * comparisonSize; + value += 1; + + // Constrain the length of x. + if (strlen(x) != value) return; + + // Test relational operators. + clang_analyzer_eval(strlen(x) >= 2); // expected-warning{{TRUE}} + clang_analyzer_eval(2 <= strlen(x)); // expected-warning{{TRUE}} + + // Test equality operators. + clang_analyzer_eval(strlen(x) != 1); // expected-warning{{TRUE}} + clang_analyzer_eval(1 != strlen(x)); // expected-warning{{TRUE}} +} diff --git a/test/Analysis/constant-folding.c b/test/Analysis/constant-folding.c index e7a5705fa59a..81d119392658 100644 --- a/test/Analysis/constant-folding.c +++ b/test/Analysis/constant-folding.c @@ -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,64 +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; + + clang_analyzer_eval(a <= b); // expected-warning{{TRUE}} + clang_analyzer_eval(b >= a); // expected-warning{{TRUE}} + clang_analyzer_eval(a != b); // expected-warning{{TRUE}} } diff --git a/test/Analysis/coverage.c b/test/Analysis/coverage.c index 73d78da18644..811691391eb1 100644 --- a/test/Analysis/coverage.c +++ b/test/Analysis/coverage.c @@ -92,3 +92,11 @@ void coverage9(int *x) { function_which_gives_up_settonull(&x); y = (*x); // no warning } + +static void empty_function(){ +} +int use_empty_function(int x) { + x = 0; + empty_function(); + return 5/x; //expected-warning {{Division by zero}} +} diff --git a/test/Analysis/cstring-syntax.c b/test/Analysis/cstring-syntax.c index 64ecb67008f8..4aa88ed3b7ed 100644 --- a/test/Analysis/cstring-syntax.c +++ b/test/Analysis/cstring-syntax.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument -Wno-sizeof-pointer-memaccess -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -Wno-strncat-size -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument -Wno-sizeof-pointer-memaccess -verify %s typedef __SIZE_TYPE__ size_t; char *strncat(char *, const char *, size_t); diff --git a/test/Analysis/ctor-inlining.mm b/test/Analysis/ctor-inlining.mm new file mode 100644 index 000000000000..54d51b46dc5e --- /dev/null +++ b/test/Analysis/ctor-inlining.mm @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -cfg-add-implicit-dtors -Wno-null-dereference -verify %s + +void clang_analyzer_eval(bool); + +struct Wrapper { + __strong id obj; +}; + +void test() { + Wrapper w; + // force a diagnostic + *(char *)0 = 1; // expected-warning{{Dereference of null pointer}} +} + + +struct IntWrapper { + int x; +}; + +void testCopyConstructor() { + IntWrapper a; + a.x = 42; + + IntWrapper b(a); + clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}} +} + +struct NonPODIntWrapper { + int x; + + virtual int get(); +}; + +void testNonPODCopyConstructor() { + NonPODIntWrapper a; + a.x = 42; + + NonPODIntWrapper b(a); + clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}} +} + diff --git a/test/Analysis/cxx-crashes.cpp b/test/Analysis/cxx-crashes.cpp index 17fc74d06f46..8912bf68de3f 100644 --- a/test/Analysis/cxx-crashes.cpp +++ b/test/Analysis/cxx-crashes.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s + +void clang_analyzer_eval(bool); int f1(char *dst) { char *p = dst + 4; @@ -54,3 +56,22 @@ struct C { void C::f() { } } + + +void vla(int n) { + int nums[n]; + nums[0] = 1; + clang_analyzer_eval(nums[0] == 1); // expected-warning{{TRUE}} + + // This used to fail with MallocChecker on, and /only/ in C++ mode. + // This struct is POD, though, so it should be fine to put it in a VLA. + struct { int x; } structs[n]; + structs[0].x = 1; + clang_analyzer_eval(structs[0].x == 1); // expected-warning{{TRUE}} +} + +void useIntArray(int []); +void testIntArrayLiteral() { + useIntArray((int []){ 1, 2, 3 }); +} + diff --git a/test/Analysis/cxx-for-range-cfg.cpp b/test/Analysis/cxx-for-range-cfg.cpp new file mode 100644 index 000000000000..e258c7a1e208 --- /dev/null +++ b/test/Analysis/cxx-for-range-cfg.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -Wall -fsyntax-only %s -std=c++11 -verify + +// The rdar11671507_vector<int *>[]> would previously crash CFG construction +// because of the temporary array of vectors. +template <typename T> +class rdar11671507_vector { +public: + rdar11671507_vector(); + ~rdar11671507_vector(); + T *Base; + T *End; +}; + +void rdar11671507(rdar11671507_vector<int*> v, rdar11671507_vector<int*> w) { + for (auto &vec : (rdar11671507_vector<int *>[]){ v, w }) {} // expected-warning {{unused}} +} diff --git a/test/Analysis/cxx-method-names.cpp b/test/Analysis/cxx-method-names.cpp new file mode 100644 index 000000000000..8afbb85c1730 --- /dev/null +++ b/test/Analysis/cxx-method-names.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,osx,experimental.unix,experimental.security.taint -analyzer-store region -verify %s + +class Evil { +public: + void system(int); // taint checker + void malloc(void *); // taint checker, malloc checker + void free(); // malloc checker, keychain checker + void fopen(); // stream checker + void feof(int, int); // stream checker + void open(); // unix api checker +}; + +void test(Evil &E) { + // no warnings, no crashes + E.system(0); + E.malloc(0); + E.free(); + E.fopen(); + E.feof(0,1); + E.open(); +} diff --git a/test/Analysis/cxx11-crashes.cpp b/test/Analysis/cxx11-crashes.cpp new file mode 100644 index 000000000000..16bfc891000f --- /dev/null +++ b/test/Analysis/cxx11-crashes.cpp @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -std=c++11 -verify %s + +// radar://11485149, PR12871 +class PlotPoint { + bool valid; +}; + +PlotPoint limitedFit () { + PlotPoint fit0; + fit0 = limitedFit (); + return fit0; +} + +// radar://11487541, NamespaceAlias +namespace boost {namespace filesystem3 { +class path { +public: + path(){} +}; + +}} +namespace boost +{ + namespace filesystem + { + using filesystem3::path; + } +} + +void radar11487541() { + namespace fs = boost::filesystem; + fs::path p; +} + +// PR12873 radar://11499139 +void testFloatInitializer() { + const float ysize={0.015}, xsize={0.01}; +} + + +// PR12874, radar://11487525 +template<class T> struct addr_impl_ref { + T & v_; + inline addr_impl_ref( T & v ): v_( v ) { + } + inline operator T& () const {return v_;} +}; +template<class T> struct addressof_impl { + static inline T * f( T & v, long ) { + return reinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<const volatile char &>(v))); + } +}; +template<class T> T * addressof( T & v ) { + return addressof_impl<T>::f( addr_impl_ref<T>( v ), 0 ); +} +void testRadar11487525_1(){ + bool s[25]; + addressof(s); +} + +// radar://11487525 Don't crash on CK_LValueBitCast. +bool begin(double *it) { + typedef bool type[25]; + bool *a = reinterpret_cast<type &>(*( reinterpret_cast<char *>( it ))); + return *a; +} diff --git a/test/Analysis/dead-stores.m b/test/Analysis/dead-stores.m index 083427478d7e..fe565547e12a 100644 --- a/test/Analysis/dead-stores.m +++ b/test/Analysis/dead-stores.m @@ -88,3 +88,23 @@ void rdar10591355() { RDar10591355 *p = rdar10591355_aux(); ^{ (void) p.x; }(); } + +@interface Radar11059352_1 { +@private + int *_pathString; +} +@property int *pathString; +@end +@interface Radar11059352 { +@private +Radar11059352_1 *_Path; +} +@end +@implementation Radar11059352 + +- (int*)usePath { + Radar11059352_1 *xxxxx = _Path; // no warning + int *wp = xxxxx.pathString; + return wp; +} +@end diff --git a/test/Analysis/delegates.m b/test/Analysis/delegates.m index 8f42b83b0eeb..7fc4f2bb9616 100644 --- a/test/Analysis/delegates.m +++ b/test/Analysis/delegates.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -Wno-objc-root-class -verify %s //===----------------------------------------------------------------------===// @@ -96,13 +96,12 @@ extern void *_NSConstantStringClassReference; @implementation test_6062730 - (void) foo { - NSString *str = [[NSString alloc] init]; + NSString *str = [[NSString alloc] init]; // no-warning [test_6062730 performSelectorOnMainThread:@selector(postNotification:) withObject:str waitUntilDone:1]; } - (void) bar { - NSString *str = [[NSString alloc] init]; // expected-warning{{leak}} - // FIXME: We need to resolve [self class] to 'test_6062730'. + NSString *str = [[NSString alloc] init]; // no-warning [[self class] performSelectorOnMainThread:@selector(postNotification:) withObject:str waitUntilDone:1]; } @@ -111,3 +110,21 @@ extern void *_NSConstantStringClassReference; } @end + +@interface ObjectThatRequiresDelegate : NSObject +- (id)initWithDelegate:(id)delegate; +- (id)initWithNumber:(int)num delegate:(id)delegate; +@end + + +@interface DelegateRequirerTest +@end +@implementation DelegateRequirerTest + +- (void)test { + (void)[[ObjectThatRequiresDelegate alloc] initWithDelegate:self]; + (void)[[ObjectThatRequiresDelegate alloc] initWithNumber:0 delegate:self]; + // no leak warnings -- these objects could be released in callback methods +} + +@end diff --git a/test/Analysis/derived-to-base.cpp b/test/Analysis/derived-to-base.cpp index f65b9db17b65..f8336785de8f 100644 --- a/test/Analysis/derived-to-base.cpp +++ b/test/Analysis/derived-to-base.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s + +void clang_analyzer_eval(bool); class A { protected: @@ -13,3 +15,123 @@ public: void B::f() { x = 3; } + + +class C : public B { +public: + void g() { + // This used to crash because we are upcasting through two bases. + x = 5; + } +}; + + +namespace VirtualBaseClasses { + class A { + protected: + int x; + }; + + class B : public virtual A { + public: + int getX() { return x; } + }; + + class C : public virtual A { + public: + void setX() { x = 42; } + }; + + class D : public B, public C {}; + class DV : virtual public B, public C {}; + class DV2 : public B, virtual public C {}; + + void test() { + D d; + d.setX(); + clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}} + + DV dv; + dv.setX(); + clang_analyzer_eval(dv.getX() == 42); // expected-warning{{TRUE}} + + DV2 dv2; + dv2.setX(); + clang_analyzer_eval(dv2.getX() == 42); // expected-warning{{TRUE}} + } + + + // Make sure we're consistent about the offset of the A subobject within an + // Intermediate virtual base class. + class Padding1 { int unused; }; + class Padding2 { int unused; }; + class Intermediate : public Padding1, public A, public Padding2 {}; + + class BI : public virtual Intermediate { + public: + int getX() { return x; } + }; + + class CI : public virtual Intermediate { + public: + void setX() { x = 42; } + }; + + class DI : public BI, public CI {}; + + void testIntermediate() { + DI d; + d.setX(); + clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}} + } +} + + +namespace DynamicVirtualUpcast { + class A { + public: + virtual ~A(); + }; + + class B : virtual public A {}; + class C : virtual public B {}; + class D : virtual public C {}; + + bool testCast(A *a) { + return dynamic_cast<B*>(a) && dynamic_cast<C*>(a); + } + + void test() { + D d; + clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}} + } +} + +namespace DynamicMultipleInheritanceUpcast { + class B { + public: + virtual ~B(); + }; + class C { + public: + virtual ~C(); + }; + class D : public B, public C {}; + + bool testCast(B *a) { + return dynamic_cast<C*>(a); + } + + void test() { + D d; + clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}} + } + + + class DV : virtual public B, virtual public C {}; + + void testVirtual() { + DV d; + clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}} + } +} diff --git a/test/Analysis/diagnostics/undef-value-callee.h b/test/Analysis/diagnostics/undef-value-callee.h new file mode 100644 index 000000000000..ea48c46a62c1 --- /dev/null +++ b/test/Analysis/diagnostics/undef-value-callee.h @@ -0,0 +1,4 @@ + +void callee() { + ; +} diff --git a/test/Analysis/diagnostics/undef-value-caller.c b/test/Analysis/diagnostics/undef-value-caller.c new file mode 100644 index 000000000000..928839d0404d --- /dev/null +++ b/test/Analysis/diagnostics/undef-value-caller.c @@ -0,0 +1,238 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist -o %t %s +// RUN: FileCheck --input-file %t %s + +#include "undef-value-callee.h" + +// This code used to cause a crash since we were not adding fileID of the header to the plist diagnostic. +// Note, in the future, we do not even need to step into this callee since it does not influence the result. +int test_calling_unimportant_callee(int argc, char *argv[]) { + int x; + callee(); + return x; // expected-warning {{Undefined or garbage value returned to caller}} +} + +// CHECK: <?xml version="1.0" encoding="UTF-8"?> +// CHECK: <plist version="1.0"> +// CHECK: <dict> +// CHECK: <key>files</key> +// CHECK: <array> +// CHECK: </array> +// CHECK: <key>diagnostics</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>9</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>9</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>9</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'x' declared without an initial value</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'x' declared without an initial value</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>9</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>9</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'callee'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'callee'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>2</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>1</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'test_calling_unimportant_callee'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'test_calling_unimportant_callee'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Returning from 'callee'</string> +// CHECK: <key>message</key> +// CHECK: <string>Returning from 'callee'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>11</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>11</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>11</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>11</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>11</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Undefined or garbage value returned to caller</string> +// CHECK: <key>message</key> +// CHECK: <string>Undefined or garbage value returned to caller</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Undefined or garbage value returned to caller</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Garbage return value</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>test_calling_unimportant_callee</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>11</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </plist> diff --git a/test/Analysis/domtest.c b/test/Analysis/domtest.c index 245186a1c239..0f370db5c132 100644 --- a/test/Analysis/domtest.c +++ b/test/Analysis/domtest.c @@ -1,4 +1,6 @@ -// RUN: %clang -cc1 -analyze -analyzer-checker=debug.DumpDominators %s 2>&1 | FileCheck %s +// RUN: rm -f %t +// RUN: %clang -cc1 -analyze -analyzer-checker=debug.DumpDominators %s > %t 2>&1 +// RUN: FileCheck --input-file=%t %s // Test the DominatorsTree implementation with various control flows int test1() @@ -24,13 +26,13 @@ int test1() // CHECK: Immediate dominance tree (Node#,IDom#): // CHECK: (0,1) -// CHECK: (1,2) -// CHECK: (2,8) -// CHECK: (3,4) -// CHECK: (4,7) -// CHECK: (5,7) +// CHECK: (1,7) +// CHECK: (2,3) +// CHECK: (3,6) +// CHECK: (4,6) +// CHECK: (5,6) // CHECK: (6,7) -// CHECK: (7,2) +// CHECK: (7,8) // CHECK: (8,9) // CHECK: (9,9) @@ -55,9 +57,9 @@ int test2() // CHECK: Immediate dominance tree (Node#,IDom#): // CHECK: (0,1) // CHECK: (1,6) -// CHECK: (2,6) +// CHECK: (2,3) // CHECK: (3,4) -// CHECK: (4,2) +// CHECK: (4,6) // CHECK: (5,6) // CHECK: (6,7) // CHECK: (7,7) @@ -83,11 +85,11 @@ int test3() // CHECK: Immediate dominance tree (Node#,IDom#): // CHECK: (0,1) // CHECK: (1,7) -// CHECK: (2,7) +// CHECK: (2,5) // CHECK: (3,4) -// CHECK: (4,2) +// CHECK: (4,5) // CHECK: (5,6) -// CHECK: (6,4) +// CHECK: (6,7) // CHECK: (7,8) // CHECK: (8,8) @@ -108,16 +110,16 @@ int test4() // CHECK: Immediate dominance tree (Node#,IDom#): // CHECK: (0,1) -// CHECK: (1,2) -// CHECK: (2,11) -// CHECK: (3,10) -// CHECK: (4,10) -// CHECK: (5,6) -// CHECK: (6,4) -// CHECK: (7,10) +// CHECK: (1,10) +// CHECK: (2,9) +// CHECK: (3,4) +// CHECK: (4,5) +// CHECK: (5,9) +// CHECK: (6,7) +// CHECK: (7,8) // CHECK: (8,9) -// CHECK: (9,7) -// CHECK: (10,2) +// CHECK: (9,10) +// CHECK: (10,11) // CHECK: (11,12) // CHECK: (12,12) @@ -163,3 +165,4 @@ int test5() // CHECK: (10,11) // CHECK: (11,11) + diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp index 8d63cc47bed4..620994858c7c 100644 --- a/test/Analysis/dtor.cpp +++ b/test/Analysis/dtor.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -Wno-null-dereference -verify %s + +void clang_analyzer_eval(bool); class A { public: @@ -11,3 +13,163 @@ public: int main() { A a; } + + +typedef __typeof(sizeof(int)) size_t; +void *malloc(size_t); +void free(void *); + +class SmartPointer { + void *X; +public: + SmartPointer(void *x) : X(x) {} + ~SmartPointer() { + free(X); + } +}; + +void testSmartPointer() { + char *mem = (char*)malloc(4); + { + SmartPointer Deleter(mem); + // destructor called here + } + *mem = 0; // expected-warning{{Use of memory after it is freed}} +} + + +void doSomething(); +void testSmartPointer2() { + char *mem = (char*)malloc(4); + { + SmartPointer Deleter(mem); + // Remove dead bindings... + doSomething(); + // destructor called here + } + *mem = 0; // expected-warning{{Use of memory after it is freed}} +} + + +class Subclass : public SmartPointer { +public: + Subclass(void *x) : SmartPointer(x) {} +}; + +void testSubclassSmartPointer() { + char *mem = (char*)malloc(4); + { + Subclass Deleter(mem); + // Remove dead bindings... + doSomething(); + // destructor called here + } + *mem = 0; // expected-warning{{Use of memory after it is freed}} +} + + +class MultipleInheritance : public Subclass, public SmartPointer { +public: + MultipleInheritance(void *a, void *b) : Subclass(a), SmartPointer(b) {} +}; + +void testMultipleInheritance1() { + char *mem = (char*)malloc(4); + { + MultipleInheritance Deleter(mem, 0); + // Remove dead bindings... + doSomething(); + // destructor called here + } + *mem = 0; // expected-warning{{Use of memory after it is freed}} +} + +void testMultipleInheritance2() { + char *mem = (char*)malloc(4); + { + MultipleInheritance Deleter(0, mem); + // Remove dead bindings... + doSomething(); + // destructor called here + } + *mem = 0; // expected-warning{{Use of memory after it is freed}} +} + +void testMultipleInheritance3() { + char *mem = (char*)malloc(4); + { + MultipleInheritance Deleter(mem, mem); + // Remove dead bindings... + doSomething(); + // destructor called here + // expected-warning@27 {{Attempt to free released memory}} + } +} + + +class SmartPointerMember { + SmartPointer P; +public: + SmartPointerMember(void *x) : P(x) {} +}; + +void testSmartPointerMember() { + char *mem = (char*)malloc(4); + { + SmartPointerMember Deleter(mem); + // Remove dead bindings... + doSomething(); + // destructor called here + } + *mem = 0; // expected-warning{{Use of memory after it is freed}} +} + + +struct IntWrapper { + IntWrapper() : x(0) {} + ~IntWrapper(); + int *x; +}; + +void testArrayInvalidation() { + int i = 42; + int j = 42; + + { + IntWrapper arr[2]; + + // There should be no undefined value warnings here. + // Eventually these should be TRUE as well, but right now + // we can't handle array constructors. + clang_analyzer_eval(arr[0].x == 0); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(arr[1].x == 0); // expected-warning{{UNKNOWN}} + + arr[0].x = &i; + arr[1].x = &j; + clang_analyzer_eval(*arr[0].x == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(*arr[1].x == 42); // expected-warning{{TRUE}} + } + + // The destructors should have invalidated i and j. + clang_analyzer_eval(i == 42); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}} +} + + + +// Don't crash on a default argument inside an initializer. +struct DefaultArg { + DefaultArg(int x = 0) {} + ~DefaultArg(); +}; + +struct InheritsDefaultArg : DefaultArg { + InheritsDefaultArg() {} + virtual ~InheritsDefaultArg(); +}; + +void testDefaultArg() { + InheritsDefaultArg a; + // Force a bug to be emitted. + *(char *)0 = 1; // expected-warning{{Dereference of null pointer}} +} diff --git a/test/Analysis/dynamic-cast.cpp b/test/Analysis/dynamic-cast.cpp index 8e63b2bcb363..b1133ac2bee5 100644 --- a/test/Analysis/dynamic-cast.cpp +++ b/test/Analysis/dynamic-cast.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core -verify %s +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=none -verify %s + +void clang_analyzer_eval(bool); class A { public: @@ -196,6 +198,9 @@ int testDynCastMostLikelyWillFail(C *c) { } else { res = 0; } + + // Note: IPA is turned off for this test because the code below shows how the + // dynamic_cast could succeed. return *res; // expected-warning{{Dereference of null pointer}} } @@ -205,7 +210,25 @@ void callTestDynCastMostLikelyWillFail() { testDynCastMostLikelyWillFail(&m); } + +void testDynCastToMiddleClass () { + class BBB : public BB {}; + BBB obj; + A &ref = obj; + + // These didn't always correctly layer base regions. + B *ptr = dynamic_cast<B*>(&ref); + clang_analyzer_eval(ptr != 0); // expected-warning{{TRUE}} + + // This is actually statically resolved to be a DerivedToBase cast. + ptr = dynamic_cast<B*>(&obj); + clang_analyzer_eval(ptr != 0); // expected-warning{{TRUE}} +} + + +// ----------------------------- // False positives/negatives. +// ----------------------------- // Due to symbolic regions not being typed. int testDynCastFalsePositive(BB *c) { diff --git a/test/Analysis/engine/replay-without-inlining.c b/test/Analysis/engine/replay-without-inlining.c new file mode 100644 index 000000000000..9ec2d08f3993 --- /dev/null +++ b/test/Analysis/engine/replay-without-inlining.c @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -verify %s + +typedef struct { + char I[4]; + int S; +} Hdr; +typedef struct { + short w; +} Hdr2; +typedef struct { + Hdr2 usedtobeundef; +} Info; +typedef struct { + const unsigned char *ib; + int cur; + int end; +} IB; +inline unsigned long gl(IB *input); +inline void gbs(IB *input, unsigned char *buf, int count); +void getB(IB *st, Hdr2 *usedtobeundef); +inline unsigned char gb(IB *input) { + if (input->cur + 1 > input->end) + ; + return input->ib[(input->cur)++]; +} +static void getID(IB *st, char str[4]) { + str[0] = gb(st); + str[1] = gb(st); + str[2] = gb(st); + str[3] = gb(st); +} +static void getH(IB *st, Hdr *header) { + getID (st, header->I); + header->S = gl(st); +} +static void readILBM(IB *st, Info *pic) { + // Initialize field; + pic->usedtobeundef.w = 5; + + // Time out in the function so that we will be forced to retry with no inlining. + Hdr header; + getH (st, &header); + getID(st, header.I); + int i = 0; + while (st->cur < st->end && i < 4) { + i++; + getH (st, &header); + } +} +int bitmapImageRepFromIFF(IB st, const unsigned char *ib, int il) { + Info pic; + st.ib = ib; + st.cur = 0; + st.end = il; + readILBM(&st,&pic); + return pic.usedtobeundef.w; // No undefined value warning here. +} diff --git a/test/Analysis/global-region-invalidation.c b/test/Analysis/global-region-invalidation.c index 184ffb870fb8..71a7285e1f1d 100644 --- a/test/Analysis/global-region-invalidation.c +++ b/test/Analysis/global-region-invalidation.c @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,experimental.security.taint,debug.TaintTest -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,experimental.security.taint,debug.TaintTest,debug.ExprInspection -verify %s + +void clang_analyzer_eval(int); // Note, we do need to include headers here, since the analyzer checks if the function declaration is located in a system header. #include "system-header-simulator.h" @@ -73,3 +75,12 @@ int constIntGlobExtern() { } return 0; } + +void testAnalyzerEvalIsPure() { + extern int someGlobal; + if (someGlobal == 0) { + clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} + } +} + diff --git a/test/Analysis/html-diags.c b/test/Analysis/html-diags.c index 59d81a56a4e9..b9361f72c64c 100644 --- a/test/Analysis/html-diags.c +++ b/test/Analysis/html-diags.c @@ -1,5 +1,5 @@ // RUN: mkdir %t.dir -// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %T.dir %s +// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %t.dir %s // RUN: rm -fR %t.dir // Currently this test mainly checks that the HTML diagnostics doesn't crash diff --git a/test/Analysis/initializer.cpp b/test/Analysis/initializer.cpp index 656a8bf8eed8..d43c8cfd9a0a 100644 --- a/test/Analysis/initializer.cpp +++ b/test/Analysis/initializer.cpp @@ -1,4 +1,8 @@ -// 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-implicit-dtors -std=c++11 -verify %s + +// We don't inline constructors unless we have destructors turned on. + +void clang_analyzer_eval(bool); class A { int x; @@ -7,8 +11,68 @@ public: }; A::A() : x(0) { - if (x != 0) { - int *p = 0; - *p = 0; // no-warning - } + clang_analyzer_eval(x == 0); // expected-warning{{TRUE}} +} + + +class DirectMember { + int x; +public: + DirectMember(int value) : x(value) {} + + int getX() { return x; } +}; + +void testDirectMember() { + DirectMember obj(3); + clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}} +} + + +class IndirectMember { + struct { + int x; + }; +public: + IndirectMember(int value) : x(value) {} + + int getX() { return x; } +}; + +void testIndirectMember() { + IndirectMember obj(3); + clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}} +} + + +struct DelegatingConstructor { + int x; + DelegatingConstructor(int y) { x = y; } + DelegatingConstructor() : DelegatingConstructor(42) {} +}; + +void testDelegatingConstructor() { + DelegatingConstructor obj; + clang_analyzer_eval(obj.x == 42); // expected-warning{{TRUE}} +} + + +// ------------------------------------ +// False negatives +// ------------------------------------ + +struct RefWrapper { + RefWrapper(int *p) : x(*p) {} + RefWrapper(int &r) : x(r) {} + int &x; +}; + +void testReferenceMember() { + int *p = 0; + RefWrapper X(p); // should warn in the constructor +} + +void testReferenceMember2() { + int *p = 0; + RefWrapper X(*p); // should warn here } diff --git a/test/Analysis/initializers-cfg-output.cpp b/test/Analysis/initializers-cfg-output.cpp index 8a7a3f5d013d..8aaa94cd84c7 100644 --- a/test/Analysis/initializers-cfg-output.cpp +++ b/test/Analysis/initializers-cfg-output.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -cfg-add-initializers %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s // XPASS: * class A { diff --git a/test/Analysis/inline-plist.c b/test/Analysis/inline-plist.c index 549082dc9ca2..1523e82cc2ea 100644 --- a/test/Analysis/inline-plist.c +++ b/test/Analysis/inline-plist.c @@ -1,4 +1,4 @@ -// RUN: %clang --analyze %s -Xclang -analyzer-ipa=inlining -o %t +// RUN: %clang --analyze %s -Xclang -analyzer-ipa=inlining -fblocks -o %t // RUN: FileCheck -input-file %t %s // <rdar://problem/10967815> @@ -23,6 +23,45 @@ void test_has_bug() { has_bug(0); } +void triggers_bug(int *p) { + *p = 0xDEADBEEF; +} + +// This function triggers a bug by calling triggers_bug(). The diagnostics +// should show when p is assumed to be null. +void bar(int *p) { + if (!!p) + return; + + if (p == 0) + triggers_bug(p); +} + +// ========================================================================== // +// Test inlining of blocks. +// ========================================================================== // + +void test_block__capture_null() { + int *p = 0; + ^(){ *p = 1; }(); +} + +void test_block_ret() { + int *p = ^(){ int *q = 0; return q; }(); + *p = 1; +} + +void test_block_blockvar() { + __block int *p; + ^(){ p = 0; }(); + *p = 1; +} + +void test_block_arg() { + int *p; + ^(int **q){ *q = 0; }(&p); + *p = 1; +} // CHECK: <?xml version="1.0" encoding="UTF-8"?> // CHECK: <plist version="1.0"> @@ -49,7 +88,7 @@ void test_has_bug() { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>11</integer> -// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -62,7 +101,7 @@ void test_has_bug() { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>12</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -83,7 +122,7 @@ void test_has_bug() { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>12</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -159,7 +198,7 @@ void test_has_bug() { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>14</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -180,7 +219,7 @@ void test_has_bug() { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>14</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -235,6 +274,7 @@ void test_has_bug() { // CHECK: <key>type</key><string>Division by zero</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>foo</string> +// CHECK: <key>issue_hash</key><integer>4</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>14</integer> @@ -302,7 +342,7 @@ void test_has_bug() { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>18</integer> -// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -357,6 +397,7 @@ void test_has_bug() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>has_bug</string> +// CHECK: <key>issue_hash</key><integer>1</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>19</integer> @@ -364,6 +405,785 @@ void test_has_bug() { // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Assuming 'p' is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Assuming 'p' is null</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>36</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>36</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>36</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>36</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>37</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>37</integer> +// CHECK: <key>col</key><integer>16</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>37</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>37</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>37</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'triggers_bug'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'triggers_bug'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>26</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'bar'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'bar'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>26</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>26</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>27</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>27</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>27</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>27</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>27</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: <key>message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Dereference of null pointer</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>triggers_bug</string> +// CHECK: <key>issue_hash</key><integer>1</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>27</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling anonymous block</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling anonymous block</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'test_block__capture_null'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'test_block__capture_null'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: <key>message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Dereference of null pointer</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: <key>message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Dereference of null pointer</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>test_block_ret</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: <key>message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Dereference of null pointer</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>test_block_blockvar</string> +// CHECK: <key>issue_hash</key><integer>3</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>61</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>61</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>62</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>62</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>62</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>62</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: <key>message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Dereference of null pointer</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>test_block_arg</string> +// CHECK: <key>issue_hash</key><integer>3</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> // CHECK: </array> // CHECK: </dict> // CHECK: </plist> diff --git a/test/Analysis/inline-unique-reports.c b/test/Analysis/inline-unique-reports.c index ae94267d2c25..9248ad2632f5 100644 --- a/test/Analysis/inline-unique-reports.c +++ b/test/Analysis/inline-unique-reports.c @@ -34,26 +34,26 @@ void test_bug_2() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>9</integer> +// CHECK: <key>line</key><integer>14</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>9</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>14</integer> +// CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>line</key><integer>15</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>10</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>15</integer> +// CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -64,7 +64,7 @@ void test_bug_2() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>line</key><integer>15</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -72,12 +72,12 @@ void test_bug_2() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>line</key><integer>15</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>line</key><integer>15</integer> // CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -99,9 +99,9 @@ void test_bug_2() { // CHECK: </dict> // CHECK: <key>depth</key><integer>1</integer> // CHECK: <key>extended_message</key> -// CHECK: <string>Entered call from 'test_bug_1'</string> +// CHECK: <string>Entered call from 'test_bug_2'</string> // CHECK: <key>message</key> -// CHECK: <string>Entered call from 'test_bug_1'</string> +// CHECK: <string>Entered call from 'test_bug_2'</string> // CHECK: </dict> // CHECK: <dict> // CHECK: <key>kind</key><string>control</string> @@ -117,7 +117,7 @@ void test_bug_2() { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>4</integer> -// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -172,6 +172,7 @@ void test_bug_2() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>bug</string> +// CHECK: <key>issue_hash</key><integer>1</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>5</integer> @@ -182,3 +183,4 @@ void test_bug_2() { // CHECK: </array> // CHECK: </dict> // CHECK: </plist> + diff --git a/test/Analysis/inline.c b/test/Analysis/inline.c index 0827d934614a..944e1e2985f1 100644 --- a/test/Analysis/inline.c +++ b/test/Analysis/inline.c @@ -1,8 +1,12 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-store region -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-store region -verify %s + +void clang_analyzer_eval(int); +void clang_analyzer_checkInlined(int); int test1_f1() { int y = 1; y++; + clang_analyzer_checkInlined(1); // expected-warning{{TRUE}} return y; } @@ -90,3 +94,19 @@ int test_rdar10977037() { } +// Test inlining a forward-declared function. +// This regressed when CallEvent was first introduced. +int plus1(int x); +void test() { + clang_analyzer_eval(plus1(2) == 3); // expected-warning{{TRUE}} +} + +int plus1(int x) { + return x + 1; +} + + +void never_called_by_anyone() { + clang_analyzer_checkInlined(0); // no-warning +} + diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp new file mode 100644 index 000000000000..4eaed9fed13c --- /dev/null +++ b/test/Analysis/inline.cpp @@ -0,0 +1,168 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s + +void clang_analyzer_eval(bool); +void clang_analyzer_checkInlined(bool); + +class A { +public: + int getZero() { return 0; } + virtual int getNum() { return 0; } +}; + +void test(A &a) { + clang_analyzer_eval(a.getZero() == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(a.getNum() == 0); // expected-warning{{UNKNOWN}} + + A copy(a); + clang_analyzer_eval(copy.getZero() == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(copy.getNum() == 0); // expected-warning{{TRUE}} +} + + +class One : public A { +public: + virtual int getNum() { return 1; } +}; + +void testPathSensitivity(int x) { + A a; + One b; + + A *ptr; + switch (x) { + case 0: + ptr = &a; + break; + case 1: + ptr = &b; + break; + default: + return; + } + + // This should be true on both branches. + clang_analyzer_eval(ptr->getNum() == x); // expected-warning {{TRUE}} +} + + +namespace PureVirtualParent { + class Parent { + public: + virtual int pureVirtual() const = 0; + int callVirtual() const { + return pureVirtual(); + } + }; + + class Child : public Parent { + public: + virtual int pureVirtual() const { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return 42; + } + }; + + void testVirtual() { + Child x; + + clang_analyzer_eval(x.pureVirtual() == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(x.callVirtual() == 42); // expected-warning{{TRUE}} + } +} + + +namespace PR13569 { + class Parent { + protected: + int m_parent; + virtual int impl() const = 0; + + Parent() : m_parent(0) {} + + public: + int interface() const { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return impl(); + } + }; + + class Child : public Parent { + protected: + virtual int impl() const { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return m_parent + m_child; + } + + public: + Child() : m_child(0) {} + + int m_child; + }; + + void testVirtual() { + Child x; + x.m_child = 42; + + // Don't crash when inlining and devirtualizing. + x.interface(); + } + + + class Grandchild : public Child {}; + + void testDevirtualizeToMiddle() { + Grandchild x; + x.m_child = 42; + + // Don't crash when inlining and devirtualizing. + x.interface(); + } +} + +namespace PR13569_virtual { + class Parent { + protected: + int m_parent; + virtual int impl() const = 0; + + Parent() : m_parent(0) {} + + public: + int interface() const { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return impl(); + } + }; + + class Child : virtual public Parent { + protected: + virtual int impl() const { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} + return m_parent + m_child; + } + + public: + Child() : m_child(0) {} + + int m_child; + }; + + void testVirtual() { + Child x; + x.m_child = 42; + + // Don't crash when inlining and devirtualizing. + x.interface(); + } + + + class Grandchild : virtual public Child {}; + + void testDevirtualizeToMiddle() { + Grandchild x; + x.m_child = 42; + + // Don't crash when inlining and devirtualizing. + x.interface(); + } +} diff --git a/test/Analysis/inlining/DynDispatchBifurcate.m b/test/Analysis/inlining/DynDispatchBifurcate.m new file mode 100644 index 000000000000..e78b90bb8c1f --- /dev/null +++ b/test/Analysis/inlining/DynDispatchBifurcate.m @@ -0,0 +1,181 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -verify %s + +#include "InlineObjCInstanceMethod.h" + +@interface MyParent : NSObject +- (int)getZero; +@end +@implementation MyParent +- (int)getZero { + return 0; +} +@end + +@interface PublicClass () { + int value2; +} +@property (readwrite) int value1; +- (void)setValue2:(int)newValue2; +@end + +@implementation PublicClass + +- (int)getZeroPublic { + return 0; +} + +@synthesize value1; + +- (int)value2 { + return value2; +} +- (void)setValue2:(int)newValue { + value2 = newValue; +} + +- (int)value3 { + return value3; +} +- (void)setValue3:(int)newValue { + value3 = newValue; +} + +@end + +@interface MyClassWithPublicParent : PublicClass +- (int)getZeroPublic; +@end +@implementation MyClassWithPublicParent +- (int)getZeroPublic { + return 0; +} +@end + +// Category overrides a public method. +@interface PublicSubClass (PrvateCat) + - (int) getZeroPublic; +@end +@implementation PublicSubClass (PrvateCat) +- (int)getZeroPublic { + return 0; +} +@end + + +@interface MyClass : MyParent { + int value; +} +- (int)getZero; +@property int value; +@end + +// Since class is private, we assume that it cannot be subclassed. +// False negative: this class is "privately subclassed". this is very rare +// in practice. +@implementation MyClass ++ (int) testTypeFromParam:(MyParent*) p { + int m = 0; + int z = [p getZero]; + if (z) + return 5/m; // false negative + return 5/[p getZero];// expected-warning {{Division by zero}} +} + +// Here only one definition is possible, since the declaration is not visible +// from outside. ++ (int) testTypeFromParamPrivateChild:(MyClass*) c { + int m = 0; + int z = [c getZero]; // MyClass overrides getZero to return '1'. + if (z) + return 5/m; // expected-warning {{Division by zero}} + return 5/[c getZero];//no warning +} + +- (int)getZero { + return 1; +} + +- (int)value { + return value; +} + +- (void)setValue:(int)newValue { + value = newValue; +} + +// Test ivar access. +- (int) testIvarInSelf { + value = 0; + return 5/value; // expected-warning {{Division by zero}} +} + ++ (int) testIvar: (MyClass*) p { + p.value = 0; + return 5/p.value; // expected-warning {{Division by zero}} +} + +// Test simple property access. ++ (int) testProperty: (MyClass*) p { + int x= 0; + [p setValue:0]; + return 5/[p value]; // expected-warning {{Division by zero}} +} + +@end + +// The class is prvate and is not subclassed. +int testCallToPublicAPIInParent(MyClassWithPublicParent *p) { + int m = 0; + int z = [p getZeroPublic]; + if (z) + return 5/m; // no warning + return 5/[p getZeroPublic];// expected-warning {{Division by zero}} +} + +// When the called method is public (due to it being defined outside of main file), +// split the path and analyze both branches. +// In this case, p can be either the object of type MyParent* or MyClass*: +// - If it's MyParent*, getZero returns 0. +// - If it's MyClass*, getZero returns 1 and 'return 5/m' is reachable. +// Declaration is provate, but p can be a subclass (MyClass*). +int testCallToPublicAPI(PublicClass *p) { + int m = 0; + int z = [p getZeroPublic]; + if (z) + return 5/m; // expected-warning {{Division by zero}} + return 5/[p getZeroPublic];// expected-warning {{Division by zero}} +} + +// Even though the method is privately declared in the category, the parent +// declares the method as public. Assume the instance can be subclassed. +int testCallToPublicAPICat(PublicSubClass *p) { + int m = 0; + int z = [p getZeroPublic]; + if (z) + return 5/m; // expected-warning {{Division by zero}} + return 5/[p getZeroPublic];// expected-warning {{Division by zero}} +} + +// Test public property - properties should always be inlined, regardless +// weither they are "public" or private. +int testPublicProperty(PublicClass *p) { + int x = 0; + [p setValue3:0]; + if ([p value3] != 0) + return 5/x; // expected-warning {{Division by zero}} // TODO: no warning, we should always inline the property. + return 5/[p value3];// expected-warning {{Division by zero}} +} + +int testExtension(PublicClass *p) { + int x = 0; + [p setValue2:0]; + if ([p value2] != 0) + return 5/x; // expected-warning {{Division by zero}} // TODO: no warning, we should always inline the property. + return 5/[p value2]; // expected-warning {{Division by zero}} +} + +// TODO: we do not handle synthesized properties yet. +int testPropertySynthesized(PublicClass *p) { + [p setValue1:0]; + return 5/[p value1]; +} diff --git a/test/Analysis/inlining/InlineObjCClassMethod.m b/test/Analysis/inlining/InlineObjCClassMethod.m new file mode 100644 index 000000000000..7e8b51fe0be0 --- /dev/null +++ b/test/Analysis/inlining/InlineObjCClassMethod.m @@ -0,0 +1,181 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -verify %s + +// Test inlining of ObjC class methods. + +typedef signed char BOOL; +typedef struct objc_class *Class; +typedef struct objc_object { + Class isa; +} *id; +@protocol NSObject - (BOOL)isEqual:(id)object; @end +@interface NSObject <NSObject> {} ++(id)alloc; +-(id)init; +-(id)autorelease; +-(id)copy; +- (Class)class; +-(id)retain; +@end + +// Vanila: ObjC class method is called by name. +@interface MyParent : NSObject ++ (int)getInt; +@end +@interface MyClass : MyParent ++ (int)getInt; +@end +@implementation MyClass ++ (int)testClassMethodByName { + int y = [MyClass getInt]; + return 5/y; // expected-warning {{Division by zero}} +} ++ (int)getInt { + return 0; +} +@end + +// The definition is defined by the parent. Make sure we find it and inline. +@interface MyParentDIP : NSObject ++ (int)getInt; +@end +@interface MyClassDIP : MyParentDIP +@end +@implementation MyClassDIP ++ (int)testClassMethodByName { + int y = [MyClassDIP getInt]; + return 5/y; // expected-warning {{Division by zero}} +} +@end +@implementation MyParentDIP ++ (int)getInt { + return 0; +} +@end + +// ObjC class method is called by name. Definition is in the category. +@interface AAA : NSObject +@end +@interface AAA (MyCat) ++ (int)getInt; +@end +int foo() { + int y = [AAA getInt]; + return 5/y; // expected-warning {{Division by zero}} +} +@implementation AAA +@end +@implementation AAA (MyCat) ++ (int)getInt { + return 0; +} +@end + +// ObjC class method is called by name. Definition is in the parent category. +@interface PPP : NSObject +@end +@interface PPP (MyCat) ++ (int)getInt; +@end +@interface CCC : PPP +@end +int foo4() { + int y = [CCC getInt]; + return 5/y; // expected-warning {{Division by zero}} +} +@implementation PPP +@end +@implementation PPP (MyCat) ++ (int)getInt { + return 0; +} +@end + +// There is no declaration in the class but there is one in the parent. Make +// sure we pick the definition from the class and not the parent. +@interface MyParentTricky : NSObject ++ (int)getInt; +@end +@interface MyClassTricky : MyParentTricky +@end +@implementation MyParentTricky ++ (int)getInt { + return 0; +} +@end +@implementation MyClassTricky ++ (int)getInt { + return 1; +} ++ (int)testClassMethodByName { + int y = [MyClassTricky getInt]; + return 5/y; // no-warning +} +@end + +// ObjC class method is called by unknown class declaration (passed in as a +// parameter). We should not inline in such case. +@interface MyParentUnknown : NSObject ++ (int)getInt; +@end +@interface MyClassUnknown : MyParentUnknown ++ (int)getInt; +@end +@implementation MyClassUnknown ++ (int)testClassVariableByUnknownVarDecl: (Class)cl { + int y = [cl getInt]; + return 3/y; // no-warning +} ++ (int)getInt { + return 0; +} +@end + + +// False negative. +// ObjC class method call through a decl with a known type. +// We should be able to track the type of currentClass and inline this call. +// Note, [self class] could be a subclass. Do we still want to inline here? +@interface MyClassKT : NSObject +@end +@interface MyClassKT (MyCatKT) ++ (int)getInt; +@end +@implementation MyClassKT (MyCatKT) ++ (int)getInt { + return 0; +} +@end +@implementation MyClassKT +- (int)testClassMethodByKnownVarDecl { + Class currentClass = [self class]; + int y = [currentClass getInt]; + return 5/y; // Would be great to get a warning here. +} +@end + +// Another false negative due to us not reasoning about self, which in this +// case points to the object of the class in the call site and should be equal +// to [MyParent class]. +@interface MyParentSelf : NSObject ++ (int)testSelf; +@end +@implementation MyParentSelf ++ (int)testSelf { + if (self == [MyParentSelf class]) + return 0; + else + return 1; +} +@end +@interface MyClassSelf : MyParentSelf +@end +@implementation MyClassSelf ++ (int)testClassMethodByKnownVarDecl { + int y = [MyParentSelf testSelf]; + return 5/y; // Should warn here. +} +@end +int foo2() { + int y = [MyParentSelf testSelf]; + return 5/y; // Should warn here. +} diff --git a/test/Analysis/inlining/InlineObjCInstanceMethod.h b/test/Analysis/inlining/InlineObjCInstanceMethod.h new file mode 100644 index 000000000000..bb0da280c8ef --- /dev/null +++ b/test/Analysis/inlining/InlineObjCInstanceMethod.h @@ -0,0 +1,46 @@ + +// Define a public header for the ObjC methods that are "visible" externally +// and, thus, could be sub-classed. We should explore the path on which these +// are sub-classed with unknown class by not inlining them. + +typedef signed char BOOL; +typedef struct objc_class *Class; +typedef struct objc_object { + Class isa; +} *id; +@protocol NSObject - (BOOL)isEqual:(id)object; @end +@interface NSObject <NSObject> {} ++(id)alloc; ++(id)new; +-(id)init; +-(id)autorelease; +-(id)copy; +- (Class)class; +-(id)retain; +@end + +@interface PublicClass : NSObject { + int value3; +} +- (int)getZeroPublic; + +- (int) value2; + +@property (readonly) int value1; + +@property int value3; +- (int)value3; +- (void)setValue3:(int)newValue; +@end + +@interface PublicSubClass : PublicClass +@end + +@interface PublicParent : NSObject +- (int)getZeroOverridden; +@end + +@interface PublicSubClass2 : PublicParent +- (int) getZeroOverridden; +@end + diff --git a/test/Analysis/inlining/InlineObjCInstanceMethod.m b/test/Analysis/inlining/InlineObjCInstanceMethod.m new file mode 100644 index 000000000000..31b6d5baa6f8 --- /dev/null +++ b/test/Analysis/inlining/InlineObjCInstanceMethod.m @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -verify %s + +#include "InlineObjCInstanceMethod.h" + +// Method is defined in the parent; called through self. +@interface MyParent : NSObject +- (int)getInt; +@end +@implementation MyParent +- (int)getInt { + return 0; +} +@end + +@interface MyClass : MyParent +@end +@implementation MyClass +- (int)testDynDispatchSelf { + int y = [self getInt]; + return 5/y; // expected-warning {{Division by zero}} +} + +// Get the dynamic type info from a cast (from id to MyClass*). ++ (int)testAllocInit { + MyClass *a = [[self alloc] init]; + return 5/[a getInt]; // expected-warning {{Division by zero}} +} + +// Method is called on inited object. ++ (int)testAllocInit2 { + MyClass *a = [[MyClass alloc] init]; + return 5/[a getInt]; // expected-warning {{Division by zero}} +} + +// Method is called on a parameter. ++ (int)testParam: (MyClass*) a { + return 5/[a getInt]; // expected-warning {{Division by zero}} +} + +// Method is called on a parameter of unnown type. ++ (int)testParamUnknownType: (id) a { + return 5/[a getInt]; // no warning +} + +@end + +// TODO: When method is inlined, the attribute reset should be visible. +@interface TestSettingAnAttributeInCallee : NSObject { + int _attribute; +} + - (void) method2; +@end + +@implementation TestSettingAnAttributeInCallee +- (int) method1 { + [self method2]; + return 5/_attribute; // expected-warning {{Division by zero}} +} + +- (void) method2 { + _attribute = 0; +} +@end + +@interface TestSettingAnAttributeInCaller : NSObject { + int _attribute; +} + - (int) method2; +@end + +@implementation TestSettingAnAttributeInCaller +- (void) method1 { + _attribute = 0; + [self method2]; +} + +- (int) method2 { + return 5/_attribute; // expected-warning {{Division by zero}} +} +@end + + +// Don't crash if we don't know the receiver's region. +void randomlyMessageAnObject(MyClass *arr[], int i) { + (void)[arr[i] getInt]; +}
\ No newline at end of file diff --git a/test/Analysis/inlining/ObjCDynTypePopagation.m b/test/Analysis/inlining/ObjCDynTypePopagation.m new file mode 100644 index 000000000000..4faaa2cb3033 --- /dev/null +++ b/test/Analysis/inlining/ObjCDynTypePopagation.m @@ -0,0 +1,84 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic-bifurcate -verify %s + +#include "InlineObjCInstanceMethod.h" + +void clang_analyzer_eval(int); + +PublicSubClass2 *getObj(); + +@implementation PublicParent +- (int) getZeroOverridden { + return 1; +} +- (int) getZero { + return 0; +} +@end + +@implementation PublicSubClass2 +- (int) getZeroOverridden { + return 0; +} + +/* Test that we get the right type from call to alloc. */ ++ (void) testAllocSelf { + id a = [self alloc]; + clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}} +} + + ++ (void) testAllocClass { + id a = [PublicSubClass2 alloc]; + clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}} +} + ++ (void) testAllocSuperOverriden { + id a = [super alloc]; + // Evaluates to 1 in the parent. + clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{FALSE}} +} + ++ (void) testAllocSuper { + id a = [super alloc]; + clang_analyzer_eval([a getZero] == 0); // expected-warning{{TRUE}} +} + ++ (void) testAllocInit { + id a = [[self alloc] init]; + clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}} +} + ++ (void) testNewSelf { + id a = [self new]; + clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}} +} + +// Casting to parent should not pessimize the dynamic type. ++ (void) testCastToParent { + id a = [[self alloc] init]; + PublicParent *p = a; + clang_analyzer_eval([p getZeroOverridden] == 0); // expected-warning{{TRUE}} +} + +// The type of parameter gets used. ++ (void)testTypeFromParam:(PublicParent*) p { + clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}} +} + +// Test implicit cast. +// Note, in this case, p could also be a subclass of MyParent. ++ (void) testCastFromId:(id) a { + PublicParent *p = a; + clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}} +} +@end + +// TODO: Would be nice to handle the case of dynamically obtained class info +// as well. We need a MemRegion for class types for this. +int testDynamicClass(BOOL coin) { + Class AllocClass = (coin ? [NSObject class] : [PublicSubClass2 class]); + id x = [[AllocClass alloc] init]; + if (coin) + return [x getZero]; + return 1; +} diff --git a/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m b/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m new file mode 100644 index 000000000000..739e10f2a5f9 --- /dev/null +++ b/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic-bifurcate -verify %s + +typedef signed char BOOL; +@protocol NSObject - (BOOL)isEqual:(id)object; @end +@interface NSObject <NSObject> {} ++(id)alloc; +-(id)init; ++(id)new; +-(id)autorelease; +-(id)copy; +- (Class)class; +-(id)retain; +@end +void clang_analyzer_eval(BOOL); + +@interface SomeOtherClass : NSObject +- (int)getZero; +@end +@implementation SomeOtherClass +- (int)getZero { return 0; } +@end + +@interface MyClass : NSObject +- (int)getZero; +@end + +@implementation MyClass +- (int)getZero { return 1; } + +// TODO: Not only we should correctly determine that the type of o at runtime +// is MyClass, but we should also warn about it. ++ (void) testCastToParent { + id a = [[self alloc] init]; + SomeOtherClass *o = a; + clang_analyzer_eval([o getZero] == 0); // expected-warning{{FALSE}} +} +@end diff --git a/test/Analysis/inlining/RetainCountExamples.m b/test/Analysis/inlining/RetainCountExamples.m new file mode 100644 index 000000000000..2b682c2b4bf0 --- /dev/null +++ b/test/Analysis/inlining/RetainCountExamples.m @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-ipa=dynamic-bifurcate -verify %s + +typedef signed char BOOL; +typedef struct objc_class *Class; +typedef struct objc_object { + Class isa; +} *id; +@protocol NSObject - (BOOL)isEqual:(id)object; @end +@interface NSObject <NSObject> {} ++(id)alloc; ++(id)new; +- (oneway void)release; +-(id)init; +-(id)autorelease; +-(id)copy; +- (Class)class; +-(id)retain; +@end + +@interface SelfStaysLive : NSObject +- (id)init; +@end + +@implementation SelfStaysLive +- (id)init { + return [super init]; +} +@end + +void selfStaysLive() { + SelfStaysLive *foo = [[SelfStaysLive alloc] init]; + [foo release]; +}
\ No newline at end of file diff --git a/test/Analysis/inlining/path-notes.c b/test/Analysis/inlining/path-notes.c new file mode 100644 index 000000000000..0885eafa5b93 --- /dev/null +++ b/test/Analysis/inlining/path-notes.c @@ -0,0 +1,1291 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-output=text -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-output=plist-multi-file %s -o - | FileCheck %s + +void zero(int **p) { + *p = 0; + // expected-note@-1 {{Null pointer value stored to 'a'}} +} + +void testZero(int *a) { + zero(&a); + // expected-note@-1 {{Calling 'zero'}} + // expected-note@-2 {{Returning from 'zero'}} + *a = 1; // expected-warning{{Dereference of null pointer}} + // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}} +} + + +void check(int *p) { + if (p) { + // expected-note@-1 + {{Assuming 'p' is null}} + // expected-note@-2 + {{Assuming pointer value is null}} + // expected-note@-3 + {{Taking false branch}} + return; + } + return; +} + +void testCheck(int *a) { + check(a); + // expected-note@-1 {{Calling 'check'}} + // expected-note@-2 {{Returning from 'check'}} + *a = 1; // expected-warning{{Dereference of null pointer}} + // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}} +} + + +int *getPointer(); + +void testInitCheck() { + int *a = getPointer(); + // expected-note@-1 {{Variable 'a' initialized here}} + check(a); + // expected-note@-1 {{Calling 'check'}} + // expected-note@-2 {{Returning from 'check'}} + *a = 1; // expected-warning{{Dereference of null pointer}} + // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}} +} + +void testStoreCheck(int *a) { + a = getPointer(); + // expected-note@-1 {{Value assigned to 'a'}} + check(a); + // expected-note@-1 {{Calling 'check'}} + // expected-note@-2 {{Returning from 'check'}} + *a = 1; // expected-warning{{Dereference of null pointer}} + // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}} +} + + +// CHECK: <?xml version="1.0" encoding="UTF-8"?> +// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +// CHECK: <plist version="1.0"> +// CHECK: <dict> +// CHECK: <key>files</key> +// CHECK: <array> +// CHECK: <string>{{.*}}path-notes.c</string> +// CHECK: </array> +// CHECK: <key>diagnostics</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'zero'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'zero'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>4</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'testZero'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'testZero'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>4</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>4</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>5</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>5</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>5</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>5</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>5</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Null pointer value stored to 'a'</string> +// CHECK: <key>message</key> +// CHECK: <string>Null pointer value stored to 'a'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Returning from 'zero'</string> +// CHECK: <key>message</key> +// CHECK: <string>Returning from 'zero'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: <key>message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Dereference of null pointer</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>testZero</string> +// CHECK: <key>issue_hash</key><integer>4</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'check'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'check'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'testCheck'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'testCheck'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Assuming 'p' is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Assuming 'p' is null</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Assuming pointer value is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Assuming pointer value is null</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>25</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>25</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Returning from 'check'</string> +// CHECK: <key>message</key> +// CHECK: <string>Returning from 'check'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: <key>message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Dereference of null pointer</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>testCheck</string> +// CHECK: <key>issue_hash</key><integer>4</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>40</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>40</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>40</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'a' initialized here</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'a' initialized here</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>40</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>40</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'check'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'check'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'testInitCheck'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'testInitCheck'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Assuming 'p' is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Assuming 'p' is null</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>25</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>25</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Returning from 'check'</string> +// CHECK: <key>message</key> +// CHECK: <string>Returning from 'check'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: <key>message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Dereference of null pointer</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>testInitCheck</string> +// CHECK: <key>issue_hash</key><integer>6</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Value assigned to 'a'</string> +// CHECK: <key>message</key> +// CHECK: <string>Value assigned to 'a'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'check'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'check'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'testStoreCheck'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'testStoreCheck'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Assuming 'p' is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Assuming 'p' is null</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>25</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>25</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Returning from 'check'</string> +// CHECK: <key>message</key> +// CHECK: <string>Returning from 'check'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: <key>message</key> +// CHECK: <string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Dereference of null pointer (loaded from variable 'a')</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Dereference of null pointer</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>testStoreCheck</string> +// CHECK: <key>issue_hash</key><integer>6</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </plist> diff --git a/test/Analysis/iterators.cpp b/test/Analysis/iterators.cpp deleted file mode 100644 index 1b6340b2af28..000000000000 --- a/test/Analysis/iterators.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// RUN: %clang --analyze -Xclang -analyzer-checker=core,experimental.cplusplus.Iterators -Xclang -verify %s -// XFAIL: win32 - -#include <vector> - -void fum(std::vector<int>::iterator t); - -void foo1() -{ - // iterators that are defined but not initialized - std::vector<int>::iterator it2; - fum(it2); // expected-warning{{Use of iterator that is not defined}} - *it2; // expected-warning{{Use of iterator that is not defined}} - - std::vector<int> v, vv; - std::vector<int>::iterator it = v.begin(); - fum(it); // no-warning - *it; // no-warning - // a valid iterator plus an integer is still valid - std::vector<int>::iterator et = it + 3; - while(it != et) { // no-warning - if (*it == 0) // no-warning - *it = 1; // no-warning - } - // iterators from different instances Cannot be compared - et = vv.end(); - while(it != et) // expected-warning{{Cannot compare iterators from different containers}} - ; - - for( std::vector<int>::iterator it = v.begin(); it != v.end(); it++ ) { // no-warning - if (*it == 1) // no-warning - *it = 0; // no-warning - } - - // copying a valid iterator results in a valid iterator - et = it; // no-warning - *et; // no-warning - - // any combo of valid iterator plus a constant is still valid - et = it + 2; // no-warning - *et; // no-warning - et = 2 + it; // no-warning - *et; // no-warning - et = 2 + 4 + it; // no-warning - *et; // no-warning - - // calling insert invalidates unless assigned to as result, but still - // invalidates other iterators on the same instance - it = v.insert( it, 1 ); // no-warning - *et; // expected-warning{{Attempt to use an iterator made invalid by call to 'insert'}} - ++it; // no-warning - - // calling erase invalidates the iterator - v.erase(it); // no-warning - et = it + 2; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} - et = 2 + it + 2; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} - et = 2 + it; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} - ++it; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} - it++; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} - *it; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} - it = v.insert( it, 1 ); // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} - // now valid after return from insert - *it; // no-warning -} - -// work with using namespace -void foo2() -{ - using namespace std; - - vector<int> v; - vector<int>::iterator it = v.begin(); - *it; // no-warning - v.insert( it, 1 ); // no-warning - *it; // expected-warning{{Attempt to use an iterator made invalid by call to 'insert'}} - it = v.insert( it, 1 ); // expected-warning{{Attempt to use an iterator made invalid by call to 'insert'}} - *it; // no-warning -} - -// using reserve eliminates some warnings -void foo3() -{ - std::vector<long> v; - std::vector<long>::iterator b = v.begin(); - v.reserve( 100 ); - - // iterator assigned before the reserve is still invalidated - *b; // expected-warning{{Attempt to use an iterator made invalid by call to 'reserve'}} - b = v.begin(); - v.insert( b, 1 ); // no-warning - - // iterator after assignment is still valid (probably) - *b; // no-warning -} - -// check on copying one iterator to another -void foo4() -{ - std::vector<float> v, vv; - std::vector<float>::iterator it = v.begin(); - *it; // no-warning - v = vv; - *it; // expected-warning{{Attempt to use an iterator made invalid by copying another container to its container}} -} - diff --git a/test/Analysis/ivars.m b/test/Analysis/ivars.m new file mode 100644 index 000000000000..42e92d259a9f --- /dev/null +++ b/test/Analysis/ivars.m @@ -0,0 +1,132 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s + +void clang_analyzer_eval(int); + +@interface Root { +@public + int uniqueID; +} + +- (void)refreshID; +@end + +void testInvalidation(Root *obj) { + int savedID = obj->uniqueID; + clang_analyzer_eval(savedID == obj->uniqueID); // expected-warning{{TRUE}} + + [obj refreshID]; + clang_analyzer_eval(savedID == obj->uniqueID); // expected-warning{{UNKNOWN}} +} + + +@interface Child : Root +@end + +@implementation Child +- (void)testSuperInvalidation { + int savedID = self->uniqueID; + clang_analyzer_eval(savedID == self->uniqueID); // expected-warning{{TRUE}} + + [super refreshID]; + clang_analyzer_eval(savedID == self->uniqueID); // expected-warning{{UNKNOWN}} +} +@end + + +@interface ManyIvars { + struct S { int a, b; } s; + int c; + int d; +} +@end + +struct S makeS(); + +@implementation ManyIvars + +- (void)testMultipleIvarInvalidation:(int)useConstraints { + if (useConstraints) { + if (s.a != 1) return; + if (s.b != 2) return; + if (c != 3) return; + if (d != 4) return; + return; + } else { + s.a = 1; + s.b = 2; + c = 3; + d = 4; + } + + clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(s.b == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(d == 4); // expected-warning{{TRUE}} + + d = 0; + + clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(s.b == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(d == 0); // expected-warning{{TRUE}} + + d = 4; + s = makeS(); + + clang_analyzer_eval(s.a == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(s.b == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(d == 4); // expected-warning{{TRUE}} + + s.a = 1; + + clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(s.b == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(d == 4); // expected-warning{{TRUE}} +} + ++ (void)testMultipleIvarInvalidation:(int)useConstraints + forObject:(ManyIvars *)obj { + if (useConstraints) { + if (obj->s.a != 1) return; + if (obj->s.b != 2) return; + if (obj->c != 3) return; + if (obj->d != 4) return; + return; + } else { + obj->s.a = 1; + obj->s.b = 2; + obj->c = 3; + obj->d = 4; + } + + clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->s.b == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}} + + obj->d = 0; + + clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->s.b == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->d == 0); // expected-warning{{TRUE}} + + obj->d = 4; + obj->s = makeS(); + + clang_analyzer_eval(obj->s.a == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(obj->s.b == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}} + + obj->s.a = 1; + + clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->s.b == 2); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}} +} + +@end diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c index a0c145279d92..1dc0f7837bad 100644 --- a/test/Analysis/malloc-annotations.c +++ b/test/Analysis/malloc-annotations.c @@ -70,10 +70,9 @@ void af1_c() { myglobalpointer = my_malloc(12); // no-warning } -// TODO: We will be able to handle this after we add support for tracking allocations stored in struct fields. void af1_d() { struct stuff mystuff; - mystuff.somefield = my_malloc(12); // false negative + mystuff.somefield = my_malloc(12); // expected-warning{{Memory is never released; potential leak}} } // Test that we can pass out allocated memory via pointer-to-pointer. @@ -123,12 +122,11 @@ void af2e() { free(p); // no-warning } -// This case would inflict a double-free elsewhere. -// However, this case is considered an analyzer bug since it causes false-positives. +// This case inflicts a possible double-free. void af3() { int *p = my_malloc(12); my_hold(p); - free(p); // no-warning + free(p); // expected-warning{{Attempt to free non-owned memory}} } int * af4() { diff --git a/test/Analysis/malloc-plist.c b/test/Analysis/malloc-plist.c index db2e0f01e73b..11eef3e14006 100644 --- a/test/Analysis/malloc-plist.c +++ b/test/Analysis/malloc-plist.c @@ -97,6 +97,77 @@ void LeakedSymbol(int in) { in++; } +// Tests that exercise running remove dead bindings at Call exit. +static void function_with_leak1() { + char *x = (char*)malloc(12); +} +void use_function_with_leak1() { + function_with_leak1(); + int y = 0; +} + +static void function_with_leak2() { + char *x = (char*)malloc(12); + int m = 0; +} +void use_function_with_leak2() { + function_with_leak2(); +} + +static void function_with_leak3(int y) { + char *x = (char*)malloc(12); + if (y) + y++; +} +void use_function_with_leak3(int y) { + function_with_leak3(y); +} + +static void function_with_leak4(int y) { + char *x = (char*)malloc(12); + if (y) + y++; + else + y--; +} +void use_function_with_leak4(int y) { + function_with_leak4(y); +} + +int anotherFunction5() { + return 5; +} +static int function_with_leak5() { + char *x = (char*)malloc(12); + return anotherFunction5(); +} +void use_function_with_leak5() { + function_with_leak5(); +} + +void anotherFunction6(int m) { + m++; +} +static void function_with_leak6() { + char *x = (char*)malloc(12); + anotherFunction6(3); +} +void use_function_with_leak6() { + function_with_leak6(); +} + +static void empty_function(){ +} +void use_empty_function() { + empty_function(); +} +static char *function_with_leak7() { + return (char*)malloc(12); +} +void use_function_with_leak7() { + function_with_leak7(); +} + // CHECK: <?xml version="1.0" encoding="UTF-8"?> // CHECK: <plist version="1.0"> // CHECK: <dict> @@ -122,7 +193,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>10</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -135,7 +206,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>10</integer> -// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -156,7 +227,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>10</integer> -// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -169,7 +240,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>11</integer> -// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>col</key><integer>11</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -190,7 +261,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>11</integer> -// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>col</key><integer>11</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -203,7 +274,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>11</integer> -// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>col</key><integer>23</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -253,7 +324,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>11</integer> -// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>col</key><integer>23</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -281,21 +352,6 @@ void LeakedSymbol(int in) { // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> -// CHECK: <key>ranges</key> -// CHECK: <array> -// CHECK: <array> -// CHECK: <dict> -// CHECK: <key>line</key><integer>14</integer> -// CHECK: <key>col</key><integer>5</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>14</integer> -// CHECK: <key>col</key><integer>6</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: </array> -// CHECK: </array> // CHECK: <key>depth</key><integer>0</integer> // CHECK: <key>extended_message</key> // CHECK: <string>Memory is never released; potential leak of memory pointed to by 'p'</string> @@ -308,6 +364,7 @@ void LeakedSymbol(int in) { // CHECK: <key>type</key><string>Memory leak</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>diagnosticTest</string> +// CHECK: <key>issue_hash</key><integer>5</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>14</integer> @@ -332,7 +389,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>18</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -379,7 +436,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>19</integer> -// CHECK: <key>col</key><integer>30</integer> +// CHECK: <key>col</key><integer>14</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -429,7 +486,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>19</integer> -// CHECK: <key>col</key><integer>30</integer> +// CHECK: <key>col</key><integer>14</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -469,6 +526,7 @@ void LeakedSymbol(int in) { // CHECK: <key>type</key><string>Memory leak</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>myArrayAllocation</string> +// CHECK: <key>issue_hash</key><integer>4</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>21</integer> @@ -493,7 +551,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>24</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -506,7 +564,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>24</integer> -// CHECK: <key>col</key><integer>28</integer> +// CHECK: <key>col</key><integer>23</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -556,7 +614,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>24</integer> -// CHECK: <key>col</key><integer>28</integer> +// CHECK: <key>col</key><integer>23</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -569,7 +627,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>26</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -590,7 +648,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>26</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -603,7 +661,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>26</integer> -// CHECK: <key>col</key><integer>40</integer> +// CHECK: <key>col</key><integer>24</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -653,7 +711,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>26</integer> -// CHECK: <key>col</key><integer>40</integer> +// CHECK: <key>col</key><integer>24</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -666,7 +724,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>27</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -687,7 +745,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>27</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -700,7 +758,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>27</integer> -// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>col</key><integer>9</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -750,7 +808,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>27</integer> -// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>col</key><integer>9</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -841,21 +899,6 @@ void LeakedSymbol(int in) { // CHECK: <key>col</key><integer>9</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> -// CHECK: <key>ranges</key> -// CHECK: <array> -// CHECK: <array> -// CHECK: <dict> -// CHECK: <key>line</key><integer>28</integer> -// CHECK: <key>col</key><integer>9</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>28</integer> -// CHECK: <key>col</key><integer>14</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: </array> -// CHECK: </array> // CHECK: <key>depth</key><integer>0</integer> // CHECK: <key>extended_message</key> // CHECK: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string> @@ -868,6 +911,7 @@ void LeakedSymbol(int in) { // CHECK: <key>type</key><string>Memory leak</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>reallocDiagnostics</string> +// CHECK: <key>issue_hash</key><integer>5</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>28</integer> @@ -892,7 +936,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>43</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -905,7 +949,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>43</integer> -// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>col</key><integer>21</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -969,7 +1013,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>34</integer> -// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -982,7 +1026,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>35</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1003,7 +1047,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>35</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1016,7 +1060,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>35</integer> -// CHECK: <key>col</key><integer>23</integer> +// CHECK: <key>col</key><integer>18</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1066,7 +1110,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>35</integer> -// CHECK: <key>col</key><integer>23</integer> +// CHECK: <key>col</key><integer>18</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1079,7 +1123,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>37</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1100,7 +1144,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>37</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1176,7 +1220,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>38</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1226,7 +1270,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>43</integer> -// CHECK: <key>col</key><integer>23</integer> +// CHECK: <key>col</key><integer>21</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1266,6 +1310,7 @@ void LeakedSymbol(int in) { // CHECK: <key>type</key><string>Memory leak</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_wrapper</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>45</integer> @@ -1290,7 +1335,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>59</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1303,7 +1348,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>60</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>22</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1367,7 +1412,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>52</integer> -// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1414,7 +1459,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>53</integer> -// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>col</key><integer>15</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1464,7 +1509,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>53</integer> -// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>col</key><integer>15</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1477,7 +1522,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>54</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1498,7 +1543,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>54</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1511,7 +1556,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>55</integer> -// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>col</key><integer>13</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1575,7 +1620,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>49</integer> -// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1588,7 +1633,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>50</integer> -// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1667,7 +1712,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>55</integer> -// CHECK: <key>col</key><integer>17</integer> +// CHECK: <key>col</key><integer>13</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1680,7 +1725,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>56</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1730,7 +1775,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>60</integer> -// CHECK: <key>col</key><integer>28</integer> +// CHECK: <key>col</key><integer>22</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1743,7 +1788,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>61</integer> -// CHECK: <key>col</key><integer>14</integer> +// CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1785,6 +1830,7 @@ void LeakedSymbol(int in) { // CHECK: <key>type</key><string>Use-after-free</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_double_action_call</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>61</integer> @@ -1809,7 +1855,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>74</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1822,7 +1868,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>74</integer> -// CHECK: <key>col</key><integer>35</integer> +// CHECK: <key>col</key><integer>30</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1872,7 +1918,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>74</integer> -// CHECK: <key>col</key><integer>35</integer> +// CHECK: <key>col</key><integer>30</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1885,7 +1931,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>75</integer> -// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>col</key><integer>20</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1949,7 +1995,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>65</integer> -// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1962,7 +2008,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>66</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1983,7 +2029,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>66</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1996,7 +2042,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>67</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2017,7 +2063,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>67</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2030,7 +2076,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>67</integer> -// CHECK: <key>col</key><integer>40</integer> +// CHECK: <key>col</key><integer>24</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2080,7 +2126,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>67</integer> -// CHECK: <key>col</key><integer>40</integer> +// CHECK: <key>col</key><integer>24</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2093,7 +2139,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>68</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2114,7 +2160,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>68</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2127,7 +2173,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>68</integer> -// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>col</key><integer>9</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2177,7 +2223,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>68</integer> -// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>col</key><integer>9</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2253,7 +2299,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>69</integer> -// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>col</key><integer>14</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2303,7 +2349,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>75</integer> -// CHECK: <key>col</key><integer>25</integer> +// CHECK: <key>col</key><integer>20</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2316,7 +2362,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>13</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2331,21 +2377,6 @@ void LeakedSymbol(int in) { // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> -// CHECK: <key>ranges</key> -// CHECK: <array> -// CHECK: <array> -// CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>5</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>13</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: </array> -// CHECK: </array> // CHECK: <key>depth</key><integer>0</integer> // CHECK: <key>extended_message</key> // CHECK: <string>Memory is never released; potential leak of memory pointed to by 'buf'</string> @@ -2358,6 +2389,7 @@ void LeakedSymbol(int in) { // CHECK: <key>type</key><string>Memory leak</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>reallocIntra</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>76</integer> @@ -2382,7 +2414,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>84</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2395,7 +2427,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>85</integer> -// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>col</key><integer>26</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2459,7 +2491,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>80</integer> -// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2472,7 +2504,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>81</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2493,7 +2525,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>81</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2506,7 +2538,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>81</integer> -// CHECK: <key>col</key><integer>28</integer> +// CHECK: <key>col</key><integer>24</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2585,7 +2617,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>85</integer> -// CHECK: <key>col</key><integer>28</integer> +// CHECK: <key>col</key><integer>26</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2625,6 +2657,7 @@ void LeakedSymbol(int in) { // CHECK: <key>type</key><string>Memory leak</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>use_ret</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>86</integer> @@ -2649,7 +2682,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>90</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2696,7 +2729,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>92</integer> -// CHECK: <key>col</key><integer>24</integer> +// CHECK: <key>col</key><integer>20</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2746,7 +2779,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>92</integer> -// CHECK: <key>col</key><integer>24</integer> +// CHECK: <key>col</key><integer>20</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2759,7 +2792,7 @@ void LeakedSymbol(int in) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>97</integer> -// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -2774,41 +2807,1626 @@ void LeakedSymbol(int in) { // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'm'</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'm'</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'm'</string> +// CHECK: <key>category</key><string>Memory Error</string> +// CHECK: <key>type</key><string>Memory leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>LeakedSymbol</string> +// CHECK: <key>issue_hash</key><integer>8</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>97</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>105</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> // CHECK: <key>ranges</key> // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>97</integer> +// CHECK: <key>line</key><integer>105</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>97</integer> -// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>line</key><integer>105</integer> +// CHECK: <key>col</key><integer>25</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: </array> // CHECK: <key>depth</key><integer>0</integer> // CHECK: <key>extended_message</key> -// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'm'</string> +// CHECK: <string>Calling 'function_with_leak1'</string> // CHECK: <key>message</key> -// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'm'</string> +// CHECK: <string>Calling 'function_with_leak1'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'use_function_with_leak1'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'use_function_with_leak1'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> // CHECK: </dict> // CHECK: </array> -// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'm'</string> +// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> // CHECK: <key>category</key><string>Memory Error</string> // CHECK: <key>type</key><string>Memory leak</string> // CHECK: <key>issue_context_kind</key><string>function</string> -// CHECK: <key>issue_context</key><string>LeakedSymbol</string> +// CHECK: <key>issue_context</key><string>function_with_leak1</string> +// CHECK: <key>issue_hash</key><integer>1</integer> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>97</integer> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>114</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>114</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>114</integer> +// CHECK: <key>col</key><integer>25</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'function_with_leak2'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'function_with_leak2'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>109</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'use_function_with_leak2'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'use_function_with_leak2'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>109</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>109</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>110</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>111</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>111</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>111</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>category</key><string>Memory Error</string> +// CHECK: <key>type</key><string>Memory leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>function_with_leak2</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>111</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>26</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'function_with_leak3'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'function_with_leak3'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>117</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'use_function_with_leak3'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'use_function_with_leak3'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>117</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>117</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>120</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>120</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>120</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>category</key><string>Memory Error</string> +// CHECK: <key>type</key><string>Memory leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>function_with_leak3</string> +// CHECK: <key>issue_hash</key><integer>3</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>120</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>26</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'function_with_leak4'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'function_with_leak4'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>126</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'use_function_with_leak4'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'use_function_with_leak4'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>126</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>126</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>127</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>131</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>131</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>131</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>category</key><string>Memory Error</string> +// CHECK: <key>type</key><string>Memory leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>function_with_leak4</string> +// CHECK: <key>issue_hash</key><integer>5</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>131</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>145</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>145</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>145</integer> +// CHECK: <key>col</key><integer>25</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'function_with_leak5'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'function_with_leak5'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'use_function_with_leak5'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'use_function_with_leak5'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>141</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>142</integer> +// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>142</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>142</integer> +// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>category</key><string>Memory Error</string> +// CHECK: <key>type</key><string>Memory leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>function_with_leak5</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>142</integer> +// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>156</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>156</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>156</integer> +// CHECK: <key>col</key><integer>25</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'function_with_leak6'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'function_with_leak6'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>151</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'use_function_with_leak6'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'use_function_with_leak6'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>151</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>151</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>152</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>153</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>153</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>153</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Memory is never released; potential leak of memory pointed to by 'x'</string> +// CHECK: <key>category</key><string>Memory Error</string> +// CHECK: <key>type</key><string>Memory leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>function_with_leak6</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>153</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>25</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Calling 'function_with_leak7'</string> +// CHECK: <key>message</key> +// CHECK: <string>Calling 'function_with_leak7'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>164</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Entered call from 'use_function_with_leak7'</string> +// CHECK: <key>message</key> +// CHECK: <string>Entered call from 'use_function_with_leak7'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>164</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>164</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>165</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>165</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>165</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>165</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>165</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>165</integer> +// CHECK: <key>col</key><integer>24</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>165</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>165</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>165</integer> +// CHECK: <key>col</key><integer>28</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is allocated</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>25</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>1</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Returned allocated memory</string> +// CHECK: <key>message</key> +// CHECK: <string>Returned allocated memory</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>23</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>169</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>169</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>169</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Memory is never released; potential leak</string> +// CHECK: <key>message</key> +// CHECK: <string>Memory is never released; potential leak</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Memory is never released; potential leak</string> +// CHECK: <key>category</key><string>Memory Error</string> +// CHECK: <key>type</key><string>Memory leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>use_function_with_leak7</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>169</integer> +// CHECK: <key>col</key><integer>1</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> // CHECK: </array> // CHECK: </dict> // CHECK: </plist> - diff --git a/test/Analysis/malloc-sizeof.c b/test/Analysis/malloc-sizeof.c index d2b3bcf3c84d..6eb466ac6a11 100644 --- a/test/Analysis/malloc-sizeof.c +++ b/test/Analysis/malloc-sizeof.c @@ -1,27 +1,36 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.unix.MallocSizeof -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=unix.MallocSizeof -verify %s #include <stddef.h> void *malloc(size_t size); void *calloc(size_t nmemb, size_t size); void *realloc(void *ptr, size_t size); +void free(void *ptr); struct A {}; struct B {}; -void foo() { +void foo(unsigned int unsignedInt, unsigned int readSize) { int *ip1 = malloc(sizeof(1)); int *ip2 = malloc(4 * sizeof(int)); - long *lp1 = malloc(sizeof(short)); // expected-warning {{Result of 'malloc' is converted to type 'long *', whose pointee type 'long' is incompatible with sizeof operand type 'short'}} - long *lp2 = malloc(5 * sizeof(double)); // expected-warning {{Result of 'malloc' is converted to type 'long *', whose pointee type 'long' is incompatible with sizeof operand type 'double'}} - long *lp3 = malloc(5 * sizeof(char) + 2); // expected-warning {{Result of 'malloc' is converted to type 'long *', whose pointee type 'long' is incompatible with sizeof operand type 'char'}} + long *lp1 = malloc(sizeof(short)); // expected-warning {{Result of 'malloc' is converted to a pointer of type 'long', which is incompatible with sizeof operand type 'short'}} + long *lp2 = malloc(5 * sizeof(double)); // expected-warning {{Result of 'malloc' is converted to a pointer of type 'long', which is incompatible with sizeof operand type 'double'}} + char *cp3 = malloc(5 * sizeof(char) + 2); // no warning + unsigned char *buf = malloc(readSize + sizeof(unsignedInt)); // no warning struct A *ap1 = calloc(1, sizeof(struct A)); struct A *ap2 = calloc(2, sizeof(*ap1)); - struct A *ap3 = calloc(2, sizeof(ap1)); // expected-warning {{Result of 'calloc' is converted to type 'struct A *', whose pointee type 'struct A' is incompatible with sizeof operand type 'struct A *'}} - struct A *ap4 = calloc(3, sizeof(struct A*)); // expected-warning {{Result of 'calloc' is converted to type 'struct A *', whose pointee type 'struct A' is incompatible with sizeof operand type 'struct A *'}} - struct A *ap5 = calloc(4, sizeof(struct B)); // expected-warning {{Result of 'calloc' is converted to type 'struct A *', whose pointee type 'struct A' is incompatible with sizeof operand type 'struct B'}} + struct A *ap3 = calloc(2, sizeof(ap1)); // expected-warning {{Result of 'calloc' is converted to a pointer of type 'struct A', which is incompatible with sizeof operand type 'struct A *'}} + struct A *ap4 = calloc(3, sizeof(struct A*)); // expected-warning {{Result of 'calloc' is converted to a pointer of type 'struct A', which is incompatible with sizeof operand type 'struct A *'}} + struct A *ap5 = calloc(4, sizeof(struct B)); // expected-warning {{Result of 'calloc' is converted to a pointer of type 'struct A', which is incompatible with sizeof operand type 'struct B'}} struct A *ap6 = realloc(ap5, sizeof(struct A)); - struct A *ap7 = realloc(ap5, sizeof(struct B)); // expected-warning {{Result of 'realloc' is converted to type 'struct A *', whose pointee type 'struct A' is incompatible with sizeof operand type 'struct B'}} + struct A *ap7 = realloc(ap5, sizeof(struct B)); // expected-warning {{Result of 'realloc' is converted to a pointer of type 'struct A', which is incompatible with sizeof operand type 'struct B'}} +} + +// Don't warn when the types differ only by constness. +void ignore_const() { + const char **x = (const char **)malloc(1 * sizeof(char *)); // no-warning + const char ***y = (const char ***)malloc(1 * sizeof(char *)); // expected-warning {{Result of 'malloc' is converted to a pointer of type 'const char **', which is incompatible with sizeof operand type 'char *'}} + free(x); } diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c index 3b4712320b72..f60271f39f4c 100644 --- a/test/Analysis/malloc.c +++ b/test/Analysis/malloc.c @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,experimental.core.CastSize,unix.Malloc -analyzer-store=region -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,experimental.core.CastSize,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s #include "system-header-simulator.h" +void clang_analyzer_eval(int); + typedef __typeof(sizeof(int)) size_t; void *malloc(size_t); void *valloc(size_t); @@ -8,6 +10,8 @@ void free(void *); void *realloc(void *ptr, size_t size); void *reallocf(void *ptr, size_t size); void *calloc(size_t nmemb, size_t size); +char *strdup(const char *s); +char *strndup(const char *s, size_t n); void myfoo(int *p); void myfooint(int p); @@ -15,7 +19,7 @@ char *fooRetPtr(); void f1() { int *p = malloc(12); - return; // expected-warning{{Memory is never released; potential leak}} + return; // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}} } void f2() { @@ -40,7 +44,7 @@ void reallocNotNullPtr(unsigned sizeIn) { char *p = (char*)malloc(size); if (p) { char *q = (char*)realloc(p, sizeIn); - char x = *q; // expected-warning {{Memory is never released; potential leak}} + char x = *q; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'q'}} } } @@ -65,7 +69,7 @@ void reallocSizeZero1() { char *p = malloc(12); char *r = realloc(p, 0); if (!r) { - free(p); + free(p); // expected-warning {{Attempt to free released memory}} } else { free(r); } @@ -75,7 +79,7 @@ void reallocSizeZero2() { char *p = malloc(12); char *r = realloc(p, 0); if (!r) { - free(p); + free(p); // expected-warning {{Attempt to free released memory}} } else { free(r); } @@ -98,7 +102,7 @@ void reallocSizeZero5() { } void reallocPtrZero1() { - char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak}} + char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'r'}} } void reallocPtrZero2() { @@ -243,6 +247,12 @@ void f7() { x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} } +void f8() { + char *x = (char*) malloc(4); + free(x); + char *y = strndup(x, 4); // expected-warning{{Use of memory after it is freed}} +} + void f7_realloc() { char *x = (char*) malloc(4); realloc(x,0); @@ -311,7 +321,7 @@ void nullFree() { void paramFree(int *p) { myfoo(p); free(p); // no warning - myfoo(p); // TODO: This should be a warning. + myfoo(p); // expected-warning {{Use of memory after it is freed}} } int* mallocEscapeRet() { @@ -503,20 +513,26 @@ void testMalloc() { int *x = malloc(12); StructWithPtr St; St.memP = x; - arrOfStructs[0] = St; + arrOfStructs[0] = St; // no-warning } StructWithPtr testMalloc2() { int *x = malloc(12); StructWithPtr St; St.memP = x; - return St; + return St; // no-warning } int *testMalloc3() { int *x = malloc(12); int *y = x; - return y; + return y; // no-warning +} + +void testStructLeak() { + StructWithPtr St; + St.memP = malloc(12); + return; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'St.memP'}} } void testElemRegion1() { @@ -653,10 +669,6 @@ int *specialMallocWithStruct() { } // Test various allocation/deallocation functions. - -char *strdup(const char *s); -char *strndup(const char *s, size_t n); - void testStrdup(const char *s, unsigned validIndex) { char *s2 = strdup(s); s2[validIndex + 1] = 'b';// expected-warning {{Memory is never released; potential leak}} @@ -711,6 +723,18 @@ FILE *useFunOpenNoReleaseFunction() { return f; // expected-warning{{leak}} } +static int readNothing(void *_ctx, char *buf, int size) { + return 0; +} +FILE *useFunOpenReadNoRelease() { + void *ctx = malloc(sizeof(int)); + FILE *f = funopen(ctx, readNothing, 0, 0, 0); + if (f == 0) { + free(ctx); + } + return f; // expected-warning{{leak}} +} + // Test setbuf, setvbuf. int my_main_no_warning() { char *p = malloc(100); @@ -760,10 +784,83 @@ void radar10978247_positive(int myValueSize) { return; } -// ---------------------------------------------------------------------------- -// Below are the known false positives. +// <rdar://problem/11269741> Previously this triggered a false positive +// because malloc() is known to return uninitialized memory and the binding +// of 'o' to 'p->n' was not getting propertly handled. Now we report a leak. +struct rdar11269741_a_t { + struct rdar11269741_b_t { + int m; + } n; +}; + +int rdar11269741(struct rdar11269741_b_t o) +{ + struct rdar11269741_a_t *p = (struct rdar11269741_a_t *) malloc(sizeof(*p)); + p->n = o; + return p->n.m; // expected-warning {{leak}} +} + +// Pointer arithmetic, returning an ElementRegion. +void *radar11329382(unsigned bl) { + void *ptr = malloc (16); + ptr = ptr + (2 - bl); + return ptr; // no warning +} + +void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__)); +int strcmp(const char *, const char *); +char *a (void); +void radar11270219(void) { + char *x = a(), *y = a(); + (__builtin_expect(!(x && y), 0) ? __assert_rtn(__func__, "/Users/zaks/tmp/ex.c", 24, "x && y") : (void)0); + strcmp(x, y); // no warning +} + +void radar_11358224_test_double_assign_ints_positive_2() +{ + void *ptr = malloc(16); + ptr = ptr; // expected-warning {{leak}} +} + +// Assume that functions which take a function pointer can free memory even if +// they are defined in system headers and take the const pointer to the +// allocated memory. (radar://11160612) +int const_ptr_and_callback(int, const char*, int n, void(*)(void*)); +void r11160612_1() { + char *x = malloc(12); + const_ptr_and_callback(0, x, 12, free); // no - warning +} + +// Null is passed as callback. +void r11160612_2() { + char *x = malloc(12); + const_ptr_and_callback(0, x, 12, 0); // expected-warning {{leak}} +} + +// Callback is passed to a function defined in a system header. +void r11160612_4() { + char *x = malloc(12); + sqlite3_bind_text_my(0, x, 12, free); // no - warning +} + +// Passing callbacks in a struct. +void r11160612_5(StWithCallback St) { + void *x = malloc(12); + dealocateMemWhenDoneByVal(x, St); +} +void r11160612_6(StWithCallback St) { + void *x = malloc(12); + dealocateMemWhenDoneByRef(&St, x); +} + +int mySub(int, int); +int myAdd(int, int); +int fPtr(unsigned cond, int x) { + return (cond ? mySub : myAdd)(x, x); +} + +// Test anti-aliasing. -// TODO: There should be no warning here. This one might be difficult to get rid of. void dependsOnValueOfPtr(int *g, unsigned f) { int *p; @@ -776,20 +873,147 @@ void dependsOnValueOfPtr(int *g, unsigned f) { if (p != g) free(p); else - return; // expected-warning{{Memory is never released; potential leak}} + return; // no warning return; } -// ---------------------------------------------------------------------------- -// False negatives. +int CMPRegionHeapToStack() { + int x = 0; + int *x1 = malloc(8); + int *x2 = &x; + clang_analyzer_eval(x1 == x2); // expected-warning{{FALSE}} + free(x1); + return x; +} + +int CMPRegionHeapToHeap2() { + int x = 0; + int *x1 = malloc(8); + int *x2 = malloc(8); + int *x4 = x1; + int *x5 = x2; + clang_analyzer_eval(x4 == x5); // expected-warning{{FALSE}} + free(x1); + free(x2); + return x; +} + +int CMPRegionHeapToHeap() { + int x = 0; + int *x1 = malloc(8); + int *x4 = x1; + if (x1 == x4) { + free(x1); + return 5/x; // expected-warning{{Division by zero}} + } + return x;// expected-warning{{This statement is never executed}} +} -// TODO: This requires tracking symbols stored inside the structs/arrays. -void testMalloc5() { +int HeapAssignment() { + int m = 0; + int *x = malloc(4); + int *y = x; + *x = 5; + clang_analyzer_eval(*x != *y); // expected-warning{{FALSE}} + free(x); + return 0; +} + +int *retPtr(); +int *retPtrMightAlias(int *x); +int cmpHeapAllocationToUnknown() { + int zero = 0; + int *yBefore = retPtr(); + int *m = malloc(8); + int *yAfter = retPtrMightAlias(m); + clang_analyzer_eval(yBefore == m); // expected-warning{{FALSE}} + clang_analyzer_eval(yAfter == m); // expected-warning{{FALSE}} + free(m); + return 0; +} + +void localArrayTest() { + char *p = (char*)malloc(12); + char *ArrayL[12]; + ArrayL[0] = p; // expected-warning {{leak}} +} + +void localStructTest() { StructWithPtr St; StructWithPtr *pSt = &St; - pSt->memP = malloc(12); + pSt->memP = malloc(12); // expected-warning{{Memory is never released; potential leak}} } +// Test double assignment through integers. +static long glob; +void test_double_assign_ints() +{ + void *ptr = malloc (16); // no-warning + glob = (long)(unsigned long)ptr; +} + +void test_double_assign_ints_positive() +{ + void *ptr = malloc(16); + (void*)(long)(unsigned long)ptr; // expected-warning {{unused}} expected-warning {{leak}} +} + + +void testCGContextNoLeak() +{ + void *ptr = malloc(16); + CGContextRef context = CGBitmapContextCreate(ptr); + + // Because you can get the data back out like this, even much later, + // CGBitmapContextCreate is one of our "stop-tracking" exceptions. + free(CGBitmapContextGetData(context)); +} + +void testCGContextLeak() +{ + void *ptr = malloc(16); + CGContextRef context = CGBitmapContextCreate(ptr); + // However, this time we're just leaking the data, because the context + // object doesn't escape and it hasn't been freed in this function. +} + +// Allow xpc context to escape. radar://11635258 +// TODO: Would be great if we checked that the finalize_connection_context actually releases it. +static void finalize_connection_context(void *ctx) { + int *context = ctx; + free(context); +} +void foo (xpc_connection_t peer) { + int *ctx = calloc(1, sizeof(int)); + xpc_connection_set_context(peer, ctx); + xpc_connection_set_finalizer_f(peer, finalize_connection_context); + xpc_connection_resume(peer); +} + +// Make sure we catch errors when we free in a function which does not allocate memory. +void freeButNoMalloc(int *p, int x){ + if (x) { + free(p); + //user forgot a return here. + } + free(p); // expected-warning {{Attempt to free released memory}} +} + +struct HasPtr { + int *p; +}; + +int* reallocButNoMalloc(struct HasPtr *a, int c, int size) { + int *s; + a->p = (int *)realloc(a->p, size); + if (a->p == 0) + return 0; // expected-warning{{Memory is never released; potential leak}} + return a->p; +} + +// ---------------------------------------------------------------------------- +// False negatives. + // TODO: This is another false negative. void testMallocWithParam(int **p) { *p = (int*) malloc(sizeof(int)); @@ -799,11 +1023,3 @@ void testMallocWithParam(int **p) { void testMallocWithParam_2(int **p) { *p = (int*) malloc(sizeof(int)); } - -// TODO: This should produce a warning, similar to the previous issue. -void localArrayTest() { - char *p = (char*)malloc(12); - char *ArrayL[12]; - ArrayL[0] = p; -} - diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp index 8f80b2b76f29..72b92722133b 100644 --- a/test/Analysis/malloc.cpp +++ b/test/Analysis/malloc.cpp @@ -14,3 +14,24 @@ struct Foo { Foo aFunction() { return malloc(10); } + +// Assume that functions which take a function pointer can free memory even if +// they are defined in system headers and take the const pointer to the +// allocated memory. (radar://11160612) +// Test default parameter. +int const_ptr_and_callback_def_param(int, const char*, int n, void(*)(void*) = 0); +void r11160612_3() { + char *x = (char*)malloc(12); + const_ptr_and_callback_def_param(0, x, 12); +} + +// Test member function pointer. +struct CanFreeMemory { + static void myFree(void*); +}; +//This is handled because we look at the type of the parameter(not argument). +void r11160612_3(CanFreeMemory* p) { + char *x = (char*)malloc(12); + const_ptr_and_callback_def_param(0, x, 12, p->myFree); +} + diff --git a/test/Analysis/malloc.m b/test/Analysis/malloc.m index 6c94118286ab..08206f3bf14c 100644 --- a/test/Analysis/malloc.m +++ b/test/Analysis/malloc.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -Wno-objc-root-class -fblocks %s #include "system-header-simulator-objc.h" @class NSString; diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm index 3515a4f99af0..7a9d881b1518 100644 --- a/test/Analysis/malloc.mm +++ b/test/Analysis/malloc.mm @@ -9,7 +9,6 @@ void free(void *); void testNSDatafFreeWhenDoneNoError(NSUInteger dataLength) { unsigned char *data = (unsigned char *)malloc(42); NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength]; - free(data); // no warning } void testNSDataFreeWhenDoneYES(NSUInteger dataLength) { @@ -22,6 +21,16 @@ void testNSDataFreeWhenDoneYES2(NSUInteger dataLength) { NSData *nsdata = [[NSData alloc] initWithBytesNoCopy:data length:dataLength freeWhenDone:1]; // no-warning } +void testNSStringFreeWhenDoneYES3(NSUInteger dataLength) { + unsigned char *data = (unsigned char *)malloc(42); + NSString *nsstr = [[NSString alloc] initWithBytesNoCopy:data length:dataLength encoding:NSUTF8StringEncoding freeWhenDone:1]; +} + +void testNSStringFreeWhenDoneYES4(NSUInteger dataLength) { + unichar *data = (unichar*)malloc(42); + NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:1]; + free(data); //expected-warning {{Attempt to free non-owned memory}} +} void testNSStringFreeWhenDoneYES(NSUInteger dataLength) { unsigned char *data = (unsigned char *)malloc(42); @@ -55,11 +64,17 @@ void testNSStringFreeWhenDoneNO2(NSUInteger dataLength) { NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:0]; // expected-warning{{leak}} } -// TODO: False Negative. -void testNSDatafFreeWhenDoneFN(NSUInteger dataLength) { - unsigned char *data = (unsigned char *)malloc(42); - NSData *nsdata = [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:1]; - free(data); // false negative +void testRelinquished1() { + void *data = malloc(42); + NSData *nsdata = [NSData dataWithBytesNoCopy:data length:42 freeWhenDone:1]; + free(data); // expected-warning {{Attempt to free non-owned memory}} +} + +void testRelinquished2() { + void *data = malloc(42); + NSData *nsdata; + free(data); + [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Attempt to free released memory}} } // Test CF/NS...NoCopy. PR12100: Pointers can escape when custom deallocators are provided. @@ -153,4 +168,57 @@ static void releaseDataCallback (void *info, const void *data, size_t size) { void testCGDataProviderCreateWithData() { void* b = calloc(8, 8); CGDataProviderRef p = CGDataProviderCreateWithData(0, b, 8*8, releaseDataCallback); +} + +// Assume that functions which take a function pointer can free memory even if +// they are defined in system headers and take the const pointer to the +// allocated memory. (radar://11160612) +extern CGDataProviderRef UnknownFunWithCallback(void *info, + const void *data, size_t size, + CGDataProviderReleaseDataCallback releaseData) + __attribute__((visibility("default"))); +void testUnknownFunWithCallBack() { + void* b = calloc(8, 8); + CGDataProviderRef p = UnknownFunWithCallback(0, b, 8*8, releaseDataCallback); +} + +// Test blocks. +void acceptBlockParam(void *, void (^block)(void *), unsigned); +void testCallWithBlockCallback() { + void *l = malloc(12); + acceptBlockParam(l, ^(void *i) { free(i); }, sizeof(char *)); +} + +// Test blocks in system headers. +void testCallWithBlockCallbackInSystem() { + void *l = malloc(12); + SystemHeaderFunctionWithBlockParam(l, ^(void *i) { free(i); }, sizeof(char *)); +} + +// Test escape into NSPointerArray. radar://11691035, PR13140 +void foo(NSPointerArray* pointerArray) { + + void* p1 = malloc (1024); + if (p1) { + [pointerArray addPointer:p1]; + } + + void* p2 = malloc (1024); + if (p2) { + [pointerArray insertPointer:p2 atIndex:1]; + } + + void* p3 = malloc (1024); + if (p3) { + [pointerArray replacePointerAtIndex:1 withPointer:p3]; + } + + // Freeing the buffer is allowed. + void* buffer = [pointerArray pointerAtIndex:0]; + free(buffer); +} + +void noCrashOnVariableArgumentSelector() { + NSMutableString *myString = [NSMutableString stringWithString:@"some text"]; + [myString appendFormat:@"some text = %d", 3]; }
\ No newline at end of file diff --git a/test/Analysis/method-call-path-notes.cpp b/test/Analysis/method-call-path-notes.cpp new file mode 100644 index 000000000000..fbf0cae7d8a6 --- /dev/null +++ b/test/Analysis/method-call-path-notes.cpp @@ -0,0 +1,664 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-output=text -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-output=plist-multi-file %s -o - | FileCheck %s + +// Test warning about null or uninitialized pointer values used as instance member +// calls. +class TestInstanceCall { +public: + void foo() {} +}; + +void test_ic() { + TestInstanceCall *p; // expected-note {{Variable 'p' declared without an initial value}} + p->foo(); // expected-warning {{Called C++ object pointer is uninitialized}} expected-note {{Called C++ object pointer is uninitialized}} +} + +void test_ic_null() { + TestInstanceCall *p = 0; // expected-note {{Variable 'p' initialized to a null pointer value}} + p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note {{Called C++ object pointer is null}} +} + +void test_ic_set_to_null() { + TestInstanceCall *p; + p = 0; // expected-note {{Null pointer value stored to 'p'}} + p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note {{Called C++ object pointer is null}} +} + +void test_ic_null(TestInstanceCall *p) { + if (!p) // expected-note {{Assuming pointer value is null}} expected-note {{Taking true branch}} + p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note{{Called C++ object pointer is null}} +} + +void test_ic_member_ptr() { + TestInstanceCall *p = 0; // expected-note {{Variable 'p' initialized to a null pointer value}} + typedef void (TestInstanceCall::*IC_Ptr)(); + IC_Ptr bar = &TestInstanceCall::foo; + (p->*bar)(); // expected-warning {{Called C++ object pointer is null}} expected-note{{Called C++ object pointer is null}} +} + +// CHECK: <?xml version="1.0" encoding="UTF-8"?> +// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +// CHECK: <plist version="1.0"> +// CHECK: <dict> +// CHECK: <key>files</key> +// CHECK: <array> +// CHECK: <string>{{.*}}method-call-path-notes.cpp</string> +// CHECK: </array> +// CHECK: <key>diagnostics</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>col</key><integer>21</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'p' declared without an initial value</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'p' declared without an initial value</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Called C++ object pointer is uninitialized</string> +// CHECK: <key>message</key> +// CHECK: <string>Called C++ object pointer is uninitialized</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Called C++ object pointer is uninitialized</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Called C++ object pointer is uninitialized</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>test_ic</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>13</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>21</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Called C++ object pointer is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Called C++ object pointer is null</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Called C++ object pointer is null</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Called C++ object pointer is null</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>test_ic_null</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>18</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>22</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>22</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Null pointer value stored to 'p'</string> +// CHECK: <key>message</key> +// CHECK: <string>Null pointer value stored to 'p'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Called C++ object pointer is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Called C++ object pointer is null</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Called C++ object pointer is null</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Called C++ object pointer is null</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>test_ic_set_to_null</string> +// CHECK: <key>issue_hash</key><integer>3</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Assuming pointer value is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Assuming pointer value is null</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Called C++ object pointer is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Called C++ object pointer is null</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Called C++ object pointer is null</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Called C++ object pointer is null</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>test_ic_null</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>21</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>33</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>36</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>36</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>36</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>36</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>36</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Called C++ object pointer is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Called C++ object pointer is null</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Called C++ object pointer is null</string> +// CHECK: <key>category</key><string>Logic error</string> +// CHECK: <key>type</key><string>Called C++ object pointer is null</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>test_ic_member_ptr</string> +// CHECK: <key>issue_hash</key><integer>4</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>36</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </plist> diff --git a/test/Analysis/method-call.cpp b/test/Analysis/method-call.cpp index 323fffebcdbe..91da532456d7 100644 --- a/test/Analysis/method-call.cpp +++ b/test/Analysis/method-call.cpp @@ -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}} } diff --git a/test/Analysis/misc-ps-arm.m b/test/Analysis/misc-ps-arm.m new file mode 100644 index 000000000000..a909ef13d0f8 --- /dev/null +++ b/test/Analysis/misc-ps-arm.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple thumbv7-apple-ios0.0.0 -analyze -analyzer-checker=core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s + +// <rdar://problem/11405978> - Handle casts of vectors to structs, and loading +// a value. +typedef float float32_t; +typedef __attribute__((neon_vector_type(2))) float32_t float32x2_t; + +typedef struct +{ + float x, y; +} Rdar11405978Vec; + +float32x2_t rdar11405978_bar(); +float32_t rdar11405978() { + float32x2_t v = rdar11405978_bar(); + Rdar11405978Vec w = *(Rdar11405978Vec *)&v; + return w.x; // no-warning +} diff --git a/test/Analysis/misc-ps-cxx0x.cpp b/test/Analysis/misc-ps-cxx0x.cpp index b4dee3122e2c..164af5dc3dfe 100644 --- a/test/Analysis/misc-ps-cxx0x.cpp +++ b/test/Analysis/misc-ps-cxx0x.cpp @@ -73,3 +73,17 @@ void test2() { struct RDar11178609 { ~RDar11178609() = delete; }; + +// Tests that dynamic_cast handles references to C++ classes. Previously +// this crashed. +class rdar11817693_BaseBase {}; +class rdar11817693_BaseInterface {}; +class rdar11817693_Base : public rdar11817693_BaseBase, public rdar11817693_BaseInterface {}; +class rdar11817693 : public rdar11817693_Base { + virtual void operator=(const rdar11817693_BaseBase& src); + void operator=(const rdar11817693& src); +}; +void rdar11817693::operator=(const rdar11817693& src) { + operator=(dynamic_cast<const rdar11817693_BaseBase&>(src)); +} + diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp index 8d75fb8ef350..e30cedb91189 100644 --- a/test/Analysis/misc-ps-region-store.cpp +++ b/test/Analysis/misc-ps-region-store.cpp @@ -271,13 +271,27 @@ class Rdar9212495_A : public Rdar9212495_B {}; const Rdar9212495_A& rdar9212495(const Rdar9212495_C* ptr) { const Rdar9212495_A& val = dynamic_cast<const Rdar9212495_A&>(*ptr); + // This is not valid C++; dynamic_cast with a reference type will throw an + // exception if the pointer does not match the expected type. However, our + // implementation of dynamic_cast will pass through a null pointer...or a + // "null reference"! So this branch is actually possible. if (&val == 0) { - val.bar(); // FIXME: This should eventually be a null dereference. + val.bar(); // expected-warning{{Called C++ object pointer is null}} } return val; } +const Rdar9212495_A* rdar9212495_ptr(const Rdar9212495_C* ptr) { + const Rdar9212495_A* val = dynamic_cast<const Rdar9212495_A*>(ptr); + + if (val == 0) { + val->bar(); // expected-warning{{Called C++ object pointer is null}} + } + + return val; +} + // Test constructors invalidating arguments. Previously this raised // an uninitialized value warning. extern "C" void __attribute__((noreturn)) PR9645_exit(int i); @@ -578,3 +592,37 @@ void rdar10924675(unsigned short x[], int index, int index2) { if (y == 0) return; } + +// Test handling CXXScalarValueInitExprs. +void rdar11401827() { + int x = int(); + if (!x) { + int *p = 0; + *p = 0xDEADBEEF; // expected-warning {{null pointer}} + } + else { + int *p = 0; + *p = 0xDEADBEEF; + } +} + +//===---------------------------------------------------------------------===// +// Handle inlining of C++ method calls. +//===---------------------------------------------------------------------===// + +struct A { + int *p; + void foo(int *q) { + p = q; + } + void bar() { + *p = 0; // expected-warning {{null pointer}} + } +}; + +void test_inline() { + A a; + a.foo(0); + a.bar(); +} + diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index d263d4da30cc..88860bbe10d3 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -673,7 +673,7 @@ typedef void (^RDar_7462324_Callback)(id obj); builder = ^(id object) { id x; if (object) { - builder(x); // expected-warning{{Function call argument is an uninitialized value}} + builder(x); // expected-warning{{Block call argument is an uninitialized value}} } }; builder(target); @@ -1341,3 +1341,23 @@ static unsigned rdar_11127008(void) { return values[index].value; } +// Test handling invalidating arrays passed to a block via captured +// pointer value (not a __block variable). +typedef void (^radar11125868_cb)(int *, unsigned); + +void rdar11125868_aux(radar11125868_cb cb); + +int rdar11125868() { + int integersStackArray[1]; + int *integers = integersStackArray; + rdar11125868_aux(^(int *integerValue, unsigned index) { + integers[index] = integerValue[index]; + }); + return integers[0] == 0; // no-warning +} + +int rdar11125868_positive() { + int integersStackArray[1]; + int *integers = integersStackArray; + return integers[0] == 0; // expected-warning {{he left operand of '==' is a}} +} diff --git a/test/Analysis/misc-ps.c b/test/Analysis/misc-ps.c index f81b0ddc68d2..8ff710b12f56 100644 --- a/test/Analysis/misc-ps.c +++ b/test/Analysis/misc-ps.c @@ -126,3 +126,10 @@ void rdar10686586() { } } +// This example tests CFG handling of '||' nested in a ternary expression, +// and seeing that the analyzer doesn't crash. +int isctype(char c, unsigned long f) +{ + return (c < 1 || c > 10) ? 0 : !!(c & f); +} + diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 9d2ff5b6ea37..bcc0472984e9 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -1,8 +1,8 @@ // NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued. -// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,experimental.deadcode.IdempotentOperations,experimental.core,osx.cocoa.AtSync -analyzer-store=region -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s -// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,experimental.deadcode.IdempotentOperations,experimental.core,osx.cocoa.AtSync -analyzer-store=region -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,experimental.deadcode.IdempotentOperations,experimental.core,osx.cocoa.AtSync -analyzer-store=region -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,experimental.deadcode.IdempotentOperations,experimental.core,osx.cocoa.AtSync -analyzer-store=region -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,experimental.deadcode.IdempotentOperations,experimental.core,osx.cocoa.AtSync,osx.AtomicCAS -analyzer-store=region -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,experimental.deadcode.IdempotentOperations,experimental.core,osx.cocoa.AtSync,osx.AtomicCAS -analyzer-store=region -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,experimental.deadcode.IdempotentOperations,experimental.core,osx.cocoa.AtSync,osx.AtomicCAS -analyzer-store=region -analyzer-constraints=basic -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,experimental.deadcode.IdempotentOperations,experimental.core,osx.cocoa.AtSync,osx.AtomicCAS -analyzer-store=region -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s #ifndef __clang_analyzer__ #error __clang_analyzer__ not defined @@ -494,6 +494,17 @@ int OSAtomicCompareAndSwap32Barrier(); } @end +// Do not crash when performing compare and swap on symbolic values. +typedef int int32_t; +typedef int int32; +typedef int32 Atomic32; +int OSAtomicCompareAndSwap32( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue); +void radar11390991_NoBarrier_CompareAndSwap(volatile Atomic32 *ptr, + Atomic32 old_value, + Atomic32 new_value) { + OSAtomicCompareAndSwap32(old_value, new_value, ptr); +} + // PR 4594 - This was a crash when handling casts in SimpleSValuator. void PR4594() { char *buf[1]; @@ -1345,3 +1356,20 @@ void radar9414427() { } @end +// Don't crash when a ?: is only preceded by a statement (not an expression) +// in the CFG. +void __assert_fail(); + +enum rdar1196620_e { E_A, E_B, E_C, E_D }; +struct rdar1196620_s { int ints[E_D+1]; }; + +static void rdar1196620_call_assert(struct rdar1196620_s* s) { + int i = 0; + s?(void)0:__assert_fail(); +} + +static void rdar1196620(struct rdar1196620_s* s) { + rdar1196620_call_assert(s); +} + + diff --git a/test/Analysis/new.cpp b/test/Analysis/new.cpp index 5ca8c462bdf5..fb77de22f127 100644 --- a/test/Analysis/new.cpp +++ b/test/Analysis/new.cpp @@ -1,15 +1,100 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s -// XFAIL: * +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s -void f1() { - int *n = new int; - if (*n) { // expected-warning {{Branch condition evaluates to a garbage value}} - } +void clang_analyzer_eval(bool); + +typedef __typeof__(sizeof(int)) size_t; +extern "C" void *malloc(size_t); + +int someGlobal; +void testImplicitlyDeclaredGlobalNew() { + if (someGlobal != 0) + return; + + // This used to crash because the global operator new is being implicitly + // declared and it does not have a valid source location. (PR13090) + void *x = ::operator new(0); + ::operator delete(x); + + // Check that the new/delete did not invalidate someGlobal; + clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}} +} + + +// This is the standard placement new. +inline void* operator new(size_t, void* __p) throw() +{ + return __p; +} + +void *testPlacementNew() { + int *x = (int *)malloc(sizeof(int)); + *x = 1; + clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}}; + + void *y = new (x) int; + clang_analyzer_eval(x == y); // expected-warning{{TRUE}}; + clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}}; + + return y; +} + +void *operator new(size_t, size_t, int *); +void *testCustomNew() { + int x[1] = {1}; + clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}}; + + void *y = new (0, x) int; + clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}}; + + return y; // no-warning } -void f2() { +void *operator new(size_t, void *, void *); +void *testCustomNewMalloc() { + int *x = (int *)malloc(sizeof(int)); + + // Should be no-warning (the custom allocator could have freed x). + void *y = new (0, x) int; // no-warning + + return y; +} + +void testScalarInitialization() { int *n = new int(3); + clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}} + + new (n) int(); + clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}} + + new (n) int{3}; + clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}} + + new (n) int{}; + clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}} +} + + +//-------------------------------- +// Incorrectly-modelled behavior +//-------------------------------- + +int testNoInitialization() { + int *n = new int; + + // Should warn that *n is uninitialized. if (*n) { // no-warning + return 0; } + return 1; } +int testNoInitializationPlacement() { + int n; + new (&n) int; + + // Should warn that n is uninitialized. + if (n) { // no-warning + return 0; + } + return 1; +} diff --git a/test/Analysis/nonnull.m b/test/Analysis/nonnull.m new file mode 100644 index 000000000000..c32a7f780ece --- /dev/null +++ b/test/Analysis/nonnull.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s + +@interface MyObject +- (void)takePointer:(void *)ptr __attribute__((nonnull(1))); +@end + +void testNonNullMethod(int *p, MyObject *obj) { + if (p) + return; + [obj takePointer:p]; // expected-warning{{nonnull}} +} + + +@interface Subclass : MyObject +// [[nonnull]] is an inherited attribute. +- (void)takePointer:(void *)ptr; +@end + +void testSubclass(int *p, Subclass *obj) { + if (p) + return; + [obj takePointer:p]; // expected-warning{{nonnull}} +} diff --git a/test/Analysis/nullptr.cpp b/test/Analysis/nullptr.cpp index 3119b4fc390c..050c3f8dc56a 100644 --- a/test/Analysis/nullptr.cpp +++ b/test/Analysis/nullptr.cpp @@ -55,7 +55,7 @@ void zoo2() { int **a = 0; int **b = 0; asm ("nop" - :"=a"(*a) + :"=r"(*a) :"0"(*b) // expected-warning{{Dereference of null pointer}} ); } diff --git a/test/Analysis/objc-boxing.m b/test/Analysis/objc-boxing.m new file mode 100644 index 000000000000..16915788d63a --- /dev/null +++ b/test/Analysis/objc-boxing.m @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify %s + +typedef signed char BOOL; +typedef long NSInteger; +typedef unsigned long NSUInteger; +@interface NSString @end +@interface NSString (NSStringExtensionMethods) ++ (id)stringWithUTF8String:(const char *)nullTerminatedCString; +@end + +@interface NSNumber ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (NSNumber *)numberWithShort:(short)value; ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (NSNumber *)numberWithLong:(long)value; ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (NSNumber *)numberWithLongLong:(long long)value; ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; ++ (NSNumber *)numberWithFloat:(float)value; ++ (NSNumber *)numberWithDouble:(double)value; ++ (NSNumber *)numberWithBool:(BOOL)value; ++ (NSNumber *)numberWithInteger:(NSInteger)value ; ++ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ; +@end + + +extern char *strdup(const char *str); + +id constant_string() { + return @("boxed constant string."); +} + +id dynamic_string() { + return @(strdup("boxed dynamic string")); // expected-warning{{Memory is never released; potential leak}} +} + +id const_char_pointer(int *x) { + if (x) + return @(3); + return @(*x); // expected-warning {{Dereference of null pointer (loaded from variable 'x')}} +}
\ No newline at end of file diff --git a/test/Analysis/objc-for.m b/test/Analysis/objc-for.m new file mode 100644 index 000000000000..52a55b07db5d --- /dev/null +++ b/test/Analysis/objc-for.m @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Loops,debug.ExprInspection -verify + +void clang_analyzer_eval(int); + +#define nil ((id)0) + +@protocol NSFastEnumeration +- (int)countByEnumeratingWithState:(void *)state objects:(id *)objects count:(unsigned)count; +@end + +@interface NSObject ++ (instancetype)testObject; +@end + +@interface NSEnumerator <NSFastEnumeration> +@end + +@interface NSArray : NSObject <NSFastEnumeration> +- (NSEnumerator *)objectEnumerator; +@end + +@interface NSDictionary : NSObject <NSFastEnumeration> +@end + +@interface NSMutableDictionary : NSDictionary +@end + +@interface NSSet : NSObject <NSFastEnumeration> +@end + +@interface NSPointerArray : NSObject <NSFastEnumeration> +@end + +void test() { + id x; + for (x in [NSArray testObject]) + clang_analyzer_eval(x != nil); // expected-warning{{TRUE}} + + for (x in [NSMutableDictionary testObject]) + clang_analyzer_eval(x != nil); // expected-warning{{TRUE}} + + for (x in [NSSet testObject]) + clang_analyzer_eval(x != nil); // expected-warning{{TRUE}} + + for (x in [[NSArray testObject] objectEnumerator]) + clang_analyzer_eval(x != nil); // expected-warning{{TRUE}} + + for (x in [NSPointerArray testObject]) + clang_analyzer_eval(x != nil); // expected-warning{{UNKNOWN}} +} + +void testWithVarInFor() { + for (id x in [NSArray testObject]) + clang_analyzer_eval(x != nil); // expected-warning{{TRUE}} + for (id x in [NSPointerArray testObject]) + clang_analyzer_eval(x != nil); // expected-warning{{UNKNOWN}} +} + diff --git a/test/Analysis/objc-subscript.m b/test/Analysis/objc-subscript.m new file mode 100644 index 000000000000..324bf1c785c1 --- /dev/null +++ b/test/Analysis/objc-subscript.m @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -Wno-objc-root-class %s + +typedef signed char BOOL; +typedef unsigned int NSUInteger; + +@interface NSObject ++(id)alloc; +-(id)init; +-(id)autorelease; +-(id)copy; +-(id)retain; +@end + +@interface Subscriptable : NSObject +- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)index; +- (id)objectAtIndexedSubscript:(NSUInteger)index; + +- (void)setObject:(id)obj forKeyedSubscript:(id)key; +- (id)objectForKeyedSubscript:(id)key; +@end + +@interface Test : Subscriptable +@end + +@implementation Test + +// <rdar://problem/6946338> for subscripting +- (id)storeDoesNotRetain { + Test *cell = [[[Test alloc] init] autorelease]; + + NSObject *string1 = [[NSObject alloc] init]; // expected-warning {{Potential leak}} + cell[0] = string1; + cell[self] = string1; + cell[string1] = self; + + return cell; +} + +// <rdar://problem/8824416> for subscripting +- (id)getDoesNotRetain:(BOOL)keyed { + if (keyed) + return [self[self] autorelease]; // expected-warning{{Object sent -autorelease too many times}} + else + return [self[0] autorelease]; // expected-warning{{Object sent -autorelease too many times}} +} + +// <rdar://problem/9241180> for subscripting +- (id)testUninitializedObject:(BOOL)keyed { + Test *o; + if (keyed) { + if (o[self]) // expected-warning {{Subscript access on an uninitialized object pointer}} + return o; // no-warning (sink) + } else { + if (o[0]) // expected-warning {{Subscript access on an uninitialized object pointer}} + return o; // no-warning (sink) + } + return self; +} + +- (void)testUninitializedArgument:(id)input testCase:(unsigned)testCase { + NSUInteger i; + id o; + + switch (testCase) { + case 0: + self[0] = o; // expected-warning {{Argument for subscript setter is an uninitialized value}} + break; + case 1: + self[i] = input; // expected-warning {{Subscript index is an uninitialized value}} + break; + case 2: + (void)self[i]; // expected-warning {{Subscript index is an uninitialized value}} + break; + case 3: + self[input] = o; // expected-warning {{Argument for subscript setter is an uninitialized value}} + break; + case 4: + self[o] = input; // expected-warning {{Subscript index is an uninitialized value}} + break; + case 5: + (void)self[o]; // expected-warning {{Subscript index is an uninitialized value}} + break; + default: + break; + } + +} + +@end diff --git a/test/Analysis/operator-calls.cpp b/test/Analysis/operator-calls.cpp index 73cd28ac0d56..dbc63bc4bed8 100644 --- a/test/Analysis/operator-calls.cpp +++ b/test/Analysis/operator-calls.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-ipa=inlining -verify %s +void clang_analyzer_eval(bool); + struct X0 { }; bool operator==(const X0&, const X0&); @@ -14,3 +16,17 @@ void t2() { bool PR7287(X0 a, X0 b) { return operator==(a, b); } + + +// Inlining non-static member operators mistakenly treated 'this' as the first +// argument for a while. + +struct IntComparable { + bool operator==(int x) const { + return x == 0; + } +}; + +void testMemberOperator(IntComparable B) { + clang_analyzer_eval(B == 0); // expected-warning{{TRUE}} +} diff --git a/test/Analysis/out-of-bounds.c b/test/Analysis/out-of-bounds.c index a97bba5bb3b8..c1721703fb86 100644 --- a/test/Analysis/out-of-bounds.c +++ b/test/Analysis/out-of-bounds.c @@ -128,11 +128,13 @@ void test2_multi_ok(int x) { buf[0][0] = 1; // no-warning } -// Testing if solver handles (symbol * constant) < constant +// *** FIXME *** +// We don't get a warning here yet because our symbolic constraint solving +// doesn't handle: (symbol * constant) < constant void test3(int x) { int buf[100]; if (x < 0) - buf[x] = 1; // expected-warning {{Out of bound memory access (accessed memory precedes memory block)}} + buf[x] = 1; } // *** FIXME *** diff --git a/test/Analysis/outofbound-notwork.c b/test/Analysis/outofbound-notwork.c index 45e713b6880a..c1fa2d7148e8 100644 --- a/test/Analysis/outofbound-notwork.c +++ b/test/Analysis/outofbound-notwork.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,experimental.unix,experimental.security.ArrayBound -analyzer-store=region -verify %s +// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,experimental.security.ArrayBound -analyzer-store=region -verify %s // XFAIL: * // Once we better handle modeling of sizes of VLAs, we can pull this back diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c index 2e7a7d30d67f..2783ac28313c 100644 --- a/test/Analysis/outofbound.c +++ b/test/Analysis/outofbound.c @@ -86,3 +86,39 @@ int symbolic_index2(int a) { } return 0; } + +int overflow_binary_search(double in) { + int eee = 16; + if (in < 1e-8 || in > 1e23) { + return 0; + } else { + static const double ins[] = {1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, + 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, + 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; + if (in < ins[eee]) { + eee -= 8; + } else { + eee += 8; + } + if (in < ins[eee]) { + eee -= 4; + } else { + eee += 4; + } + if (in < ins[eee]) { + eee -= 2; + } else { + eee += 2; + } + if (in < ins[eee]) { + eee -= 1; + } else { + eee += 1; + } + if (in < ins[eee]) { // expected-warning {{Access out-of-bound array element (buffer overflow)}} + eee -= 1; + } + } + return eee; +} diff --git a/test/Analysis/plist-output-alternate.m b/test/Analysis/plist-output-alternate.m index 83100dc20944..a338a79491fd 100644 --- a/test/Analysis/plist-output-alternate.m +++ b/test/Analysis/plist-output-alternate.m @@ -82,7 +82,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>5</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -137,6 +137,7 @@ void rdar8331641(int x) { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_init</string> +// CHECK: <key>issue_hash</key><integer>2</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>6</integer> @@ -161,7 +162,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>10</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -216,6 +217,7 @@ void rdar8331641(int x) { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_assign</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>12</integer> @@ -240,7 +242,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>16</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -295,6 +297,7 @@ void rdar8331641(int x) { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_assign_transitive</string> +// CHECK: <key>issue_hash</key><integer>4</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>19</integer> @@ -319,7 +322,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>23</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -332,7 +335,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>23</integer> -// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -382,7 +385,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>23</integer> -// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -437,6 +440,7 @@ void rdar8331641(int x) { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_cond</string> +// CHECK: <key>issue_hash</key><integer>2</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>24</integer> @@ -461,7 +465,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>29</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -474,7 +478,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>29</integer> -// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -495,7 +499,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>29</integer> -// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -508,7 +512,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>30</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -529,7 +533,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>30</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -584,6 +588,7 @@ void rdar8331641(int x) { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_cond_transitive</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>31</integer> @@ -608,7 +613,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>36</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -697,6 +702,7 @@ void rdar8331641(int x) { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_field</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>38</integer> @@ -721,7 +727,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>53</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -734,7 +740,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>54</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>13</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -755,7 +761,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>54</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>13</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -768,7 +774,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>54</integer> -// CHECK: <key>col</key><integer>82</integer> +// CHECK: <key>col</key><integer>36</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -818,7 +824,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>54</integer> -// CHECK: <key>col</key><integer>82</integer> +// CHECK: <key>col</key><integer>36</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -831,7 +837,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>55</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -852,7 +858,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>55</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -899,7 +905,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>57</integer> -// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>col</key><integer>14</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -920,7 +926,7 @@ void rdar8331641(int x) { // CHECK: </dict> // CHECK: <dict> // CHECK: <key>line</key><integer>57</integer> -// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>col</key><integer>14</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -960,6 +966,7 @@ void rdar8331641(int x) { // CHECK: <key>type</key><string>Leak</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>rdar8331641</string> +// CHECK: <key>issue_hash</key><integer>6</integer> // CHECK: <key>location</key> // CHECK: <dict> // CHECK: <key>line</key><integer>58</integer> diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m index 72e8f8d0aa66..769c1bc60247 100644 --- a/test/Analysis/plist-output.m +++ b/test/Analysis/plist-output.m @@ -1,5 +1,4 @@ -// RUN: %clang --analyze %s -o %t > /dev/null 2>&1 -// RUN: FileCheck -input-file %t %s +// RUN: %clang --analyze %s -o - 2>/dev/null | FileCheck %s void test_null_init(void) { int *p = 0; @@ -27,7 +26,6 @@ void test_null_cond(int *p) { void test_null_cond_transitive(int *q) { if (!q) { - // FIXME: we need a diagnostic saying that p is initialized to 0 int *p = q; *p = 0xDEADBEEF; } @@ -81,10 +79,12 @@ int test_cond_assign() { @end // CHECK: <?xml version="1.0" encoding="UTF-8"?> +// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> // CHECK: <plist version="1.0"> // CHECK: <dict> // CHECK: <key>files</key> // CHECK: <array> +// CHECK: <string>{{.*}}plist-output.m</string> // CHECK: </array> // CHECK: <key>diagnostics</key> // CHECK: <array> @@ -92,6 +92,35 @@ int test_cond_assign() { // CHECK: <key>path</key> // CHECK: <array> // CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>4</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>4</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>4</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: </dict> +// CHECK: <dict> // CHECK: <key>kind</key><string>control</string> // CHECK: <key>edges</key> // CHECK: <array> @@ -99,25 +128,25 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>5</integer> +// CHECK: <key>line</key><integer>4</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>5</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>4</integer> +// CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>6</integer> +// CHECK: <key>line</key><integer>5</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>6</integer> +// CHECK: <key>line</key><integer>5</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -129,7 +158,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>6</integer> +// CHECK: <key>line</key><integer>5</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -137,12 +166,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>6</integer> +// CHECK: <key>line</key><integer>5</integer> // CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>6</integer> +// CHECK: <key>line</key><integer>5</integer> // CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -160,9 +189,10 @@ int test_cond_assign() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_init</string> +// CHECK: <key>issue_hash</key><integer>2</integer> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>6</integer> +// CHECK: <key>line</key><integer>5</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -178,6 +208,69 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> +// CHECK: <key>line</key><integer>9</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>9</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>10</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Null pointer value stored to 'p'</string> +// CHECK: <key>message</key> +// CHECK: <string>Null pointer value stored to 'p'</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> // CHECK: <key>line</key><integer>10</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> @@ -191,12 +284,12 @@ int test_cond_assign() { // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>line</key><integer>11</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>line</key><integer>11</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -208,7 +301,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>line</key><integer>11</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -216,12 +309,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>line</key><integer>11</integer> // CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>line</key><integer>11</integer> // CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -239,9 +332,10 @@ int test_cond_assign() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_assign</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>12</integer> +// CHECK: <key>line</key><integer>11</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -257,25 +351,88 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>16</integer> +// CHECK: <key>line</key><integer>15</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>16</integer> +// CHECK: <key>line</key><integer>15</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'q' initialized to a null pointer value</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'q' initialized to a null pointer value</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>17</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>line</key><integer>18</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>line</key><integer>18</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -287,7 +444,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>line</key><integer>18</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -295,12 +452,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>line</key><integer>18</integer> // CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>line</key><integer>18</integer> // CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -318,9 +475,10 @@ int test_cond_assign() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_assign_transitive</string> +// CHECK: <key>issue_hash</key><integer>4</integer> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>19</integer> +// CHECK: <key>line</key><integer>18</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -336,26 +494,26 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>line</key><integer>22</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>23</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>22</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>line</key><integer>22</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>23</integer> -// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>line</key><integer>22</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -366,7 +524,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>line</key><integer>22</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -374,12 +532,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>line</key><integer>22</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>line</key><integer>22</integer> // CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -392,6 +550,35 @@ int test_cond_assign() { // CHECK: <string>Assuming 'p' is null</string> // CHECK: </dict> // CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>22</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>22</integer> +// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>22</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Assuming pointer value is null</string> +// CHECK: <key>message</key> +// CHECK: <string>Assuming pointer value is null</string> +// CHECK: </dict> +// CHECK: <dict> // CHECK: <key>kind</key><string>control</string> // CHECK: <key>edges</key> // CHECK: <array> @@ -399,25 +586,25 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>23</integer> +// CHECK: <key>line</key><integer>22</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>23</integer> -// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>line</key><integer>22</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>line</key><integer>23</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>line</key><integer>23</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -429,7 +616,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>line</key><integer>23</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -437,12 +624,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>line</key><integer>23</integer> // CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>line</key><integer>23</integer> // CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -460,9 +647,10 @@ int test_cond_assign() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_cond</string> +// CHECK: <key>issue_hash</key><integer>2</integer> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>24</integer> +// CHECK: <key>line</key><integer>23</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -478,26 +666,26 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>line</key><integer>28</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>29</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>line</key><integer>28</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>29</integer> -// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -512,26 +700,26 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>line</key><integer>28</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>29</integer> -// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>line</key><integer>28</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>31</integer> +// CHECK: <key>line</key><integer>29</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>31</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -539,6 +727,35 @@ int test_cond_assign() { // CHECK: </array> // CHECK: </dict> // CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: </dict> +// CHECK: <dict> // CHECK: <key>kind</key><string>control</string> // CHECK: <key>edges</key> // CHECK: <array> @@ -546,25 +763,25 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>31</integer> +// CHECK: <key>line</key><integer>29</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>31</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>line</key><integer>29</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>line</key><integer>30</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>line</key><integer>30</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -576,7 +793,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>line</key><integer>30</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -584,12 +801,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>line</key><integer>30</integer> // CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>line</key><integer>30</integer> // CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -607,9 +824,10 @@ int test_cond_assign() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_cond_transitive</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>32</integer> +// CHECK: <key>line</key><integer>30</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -625,25 +843,25 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>37</integer> +// CHECK: <key>line</key><integer>35</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>37</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>35</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>37</integer> +// CHECK: <key>line</key><integer>35</integer> // CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>37</integer> +// CHECK: <key>line</key><integer>35</integer> // CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -659,12 +877,12 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>37</integer> +// CHECK: <key>line</key><integer>35</integer> // CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>37</integer> +// CHECK: <key>line</key><integer>35</integer> // CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -672,12 +890,12 @@ int test_cond_assign() { // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>39</integer> +// CHECK: <key>line</key><integer>37</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>39</integer> +// CHECK: <key>line</key><integer>37</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -689,7 +907,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>39</integer> +// CHECK: <key>line</key><integer>37</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -697,12 +915,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>39</integer> +// CHECK: <key>line</key><integer>37</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>39</integer> +// CHECK: <key>line</key><integer>37</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -720,9 +938,10 @@ int test_cond_assign() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_null_field</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>39</integer> +// CHECK: <key>line</key><integer>37</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -738,25 +957,25 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>44</integer> +// CHECK: <key>line</key><integer>42</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>44</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>44</integer> +// CHECK: <key>line</key><integer>42</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>44</integer> +// CHECK: <key>line</key><integer>42</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -772,12 +991,12 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>44</integer> +// CHECK: <key>line</key><integer>42</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>44</integer> +// CHECK: <key>line</key><integer>42</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -785,13 +1004,13 @@ int test_cond_assign() { // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>line</key><integer>45</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>47</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -806,25 +1025,25 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>line</key><integer>45</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>47</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>line</key><integer>45</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>line</key><integer>45</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -840,12 +1059,12 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>line</key><integer>45</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>line</key><integer>45</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -853,13 +1072,13 @@ int test_cond_assign() { // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>line</key><integer>48</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>50</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -867,6 +1086,35 @@ int test_cond_assign() { // CHECK: </array> // CHECK: </dict> // CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: </dict> +// CHECK: <dict> // CHECK: <key>kind</key><string>control</string> // CHECK: <key>edges</key> // CHECK: <array> @@ -874,25 +1122,25 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>line</key><integer>48</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>50</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>line</key><integer>49</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>line</key><integer>49</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -904,7 +1152,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>line</key><integer>49</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -912,12 +1160,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>line</key><integer>49</integer> // CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>line</key><integer>49</integer> // CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -935,9 +1183,10 @@ int test_cond_assign() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_assumptions</string> +// CHECK: <key>issue_hash</key><integer>8</integer> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>line</key><integer>49</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -953,26 +1202,26 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>line</key><integer>54</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>56</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>54</integer> +// CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>line</key><integer>55</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -987,25 +1236,25 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>line</key><integer>55</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>line</key><integer>55</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>line</key><integer>55</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1017,7 +1266,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>line</key><integer>55</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1025,12 +1274,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>line</key><integer>55</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>line</key><integer>55</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1050,12 +1299,12 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>line</key><integer>55</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>line</key><integer>55</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1063,13 +1312,13 @@ int test_cond_assign() { // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>line</key><integer>57</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>59</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1084,26 +1333,26 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>line</key><integer>57</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>59</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>8</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>line</key><integer>57</integer> // CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>59</integer> -// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> @@ -1114,7 +1363,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>line</key><integer>57</integer> // CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1122,12 +1371,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>line</key><integer>57</integer> // CHECK: <key>col</key><integer>11</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>line</key><integer>57</integer> // CHECK: <key>col</key><integer>11</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1145,9 +1394,10 @@ int test_cond_assign() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>function</string> // CHECK: <key>issue_context</key><string>test_cond_assign</string> +// CHECK: <key>issue_hash</key><integer>4</integer> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>line</key><integer>57</integer> // CHECK: <key>col</key><integer>10</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1163,99 +1413,60 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>line</key><integer>74</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>line</key><integer>74</integer> +// CHECK: <key>col</key><integer>4</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>7</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>7</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: </array> -// CHECK: </dict> -// CHECK: </array> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>kind</key><string>control</string> -// CHECK: <key>edges</key> -// CHECK: <array> -// CHECK: <dict> -// CHECK: <key>start</key> -// CHECK: <array> -// CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>7</integer> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>line</key><integer>75</integer> // CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> -// CHECK: <key>end</key> -// CHECK: <array> -// CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>3</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>3</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: </array> // CHECK: </dict> // CHECK: </array> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>kind</key><string>control</string> -// CHECK: <key>edges</key> -// CHECK: <array> -// CHECK: <dict> -// CHECK: <key>start</key> -// CHECK: <array> -// CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>3</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>76</integer> -// CHECK: <key>col</key><integer>3</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: </array> -// CHECK: <key>end</key> -// CHECK: <array> -// CHECK: <dict> -// CHECK: <key>line</key><integer>77</integer> -// CHECK: <key>col</key><integer>5</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: <dict> -// CHECK: <key>line</key><integer>77</integer> -// CHECK: <key>col</key><integer>5</integer> -// CHECK: <key>file</key><integer>0</integer> -// CHECK: </dict> -// CHECK: </array> -// CHECK: </dict> -// CHECK: </array> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> +// CHECK: <key>message</key> +// CHECK: <string>Variable 'p' initialized to a null pointer value</string> // CHECK: </dict> // CHECK: <dict> // CHECK: <key>kind</key><string>control</string> @@ -1265,25 +1476,25 @@ int test_cond_assign() { // CHECK: <key>start</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>77</integer> +// CHECK: <key>line</key><integer>75</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>77</integer> -// CHECK: <key>col</key><integer>5</integer> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>7</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: </array> // CHECK: <key>end</key> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>78</integer> +// CHECK: <key>line</key><integer>76</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>78</integer> +// CHECK: <key>line</key><integer>76</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1295,7 +1506,7 @@ int test_cond_assign() { // CHECK: <key>kind</key><string>event</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>78</integer> +// CHECK: <key>line</key><integer>76</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1303,12 +1514,12 @@ int test_cond_assign() { // CHECK: <array> // CHECK: <array> // CHECK: <dict> -// CHECK: <key>line</key><integer>78</integer> +// CHECK: <key>line</key><integer>76</integer> // CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> // CHECK: <dict> -// CHECK: <key>line</key><integer>78</integer> +// CHECK: <key>line</key><integer>76</integer> // CHECK: <key>col</key><integer>6</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1326,9 +1537,10 @@ int test_cond_assign() { // CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>issue_context_kind</key><string>Objective-C method</string> // CHECK: <key>issue_context</key><string>test</string> +// CHECK: <key>issue_hash</key><integer>3</integer> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>78</integer> +// CHECK: <key>line</key><integer>76</integer> // CHECK: <key>col</key><integer>5</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> @@ -1336,4 +1548,3 @@ int test_cond_assign() { // CHECK: </array> // CHECK: </dict> // CHECK: </plist> - diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c index fb37f1c791a3..6567000c735f 100644 --- a/test/Analysis/ptr-arith.c +++ b/test/Analysis/ptr-arith.c @@ -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 - - 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(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}} + + 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) { diff --git a/test/Analysis/rdar-7168531.m b/test/Analysis/rdar-7168531.m index 151625569ca7..4ccc7d7a2b34 100644 --- a/test/Analysis/rdar-7168531.m +++ b/test/Analysis/rdar-7168531.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -triple i386-apple-darwin10 -fobjc-fragile-abi -analyzer-store=region %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -analyzer-store=region %s // Note that the target triple is important for this test case. It specifies that we use the // fragile Objective-C ABI. diff --git a/test/Analysis/refcnt_naming.m b/test/Analysis/refcnt_naming.m index aff713be49f2..1d3a9b7589e3 100644 --- a/test/Analysis/refcnt_naming.m +++ b/test/Analysis/refcnt_naming.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-ipa=none -analyzer-store=region -verify %s typedef const struct __CFString * CFStringRef; typedef const struct __CFAllocator * CFAllocatorRef; diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp index 5897e682884c..06e4a50e44cc 100644 --- a/test/Analysis/reference.cpp +++ b/test/Analysis/reference.cpp @@ -1,11 +1,12 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s -// XFAIL +// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s + +void clang_analyzer_eval(bool); typedef typeof(sizeof(int)) size_t; void malloc (size_t); void f1() { - int const &i = 3; // <--- **FIXME** This is currently not being modeled correctly. + int const &i = 3; int b = i; int *p = 0; @@ -56,3 +57,75 @@ char t6 (char* p) { if (*p) return *p; return *(char*)0; // no-warning } + + +// PR13440 / <rdar://problem/11977113> +// Test that the array-to-pointer decay works for array references as well. +// More generally, when we want an lvalue for a reference field, we still need +// to do one level of load. +namespace PR13440 { + typedef int T[1]; + struct S { + T &x; + + int *m() { return x; } + }; + + struct S2 { + int (&x)[1]; + + int *m() { return x; } + }; + + void test() { + int a[1]; + S s = { a }; + S2 s2 = { a }; + + if (s.x != a) return; + if (s2.x != a) return; + + a[0] = 42; + clang_analyzer_eval(s.x[0] == 42); // expected-warning{{TRUE}} + clang_analyzer_eval(s2.x[0] == 42); // expected-warning{{TRUE}} + } +} + +void testNullReference() { + int *x = 0; + int &y = *x; // expected-warning{{Dereference of null pointer}} + y = 5; +} + +void testRetroactiveNullReference(int *x) { + // According to the C++ standard, there is no such thing as a + // "null reference". So the 'if' statement ought to be dead code. + // However, Clang (and other compilers) don't actually check that a pointer + // value is non-null in the implementation of references, so it is possible + // to produce a supposed "null reference" at runtime. The analyzer shoeuld + // still warn when it can prove such errors. + int &y = *x; + if (x != 0) + return; + y = 5; // expected-warning{{Dereference of null pointer}} +} + + +// ------------------------------------ +// False negatives +// ------------------------------------ + +namespace rdar11212286 { + class B{}; + + B test() { + B *x = 0; + return *x; // should warn here! + } + + B &testRef() { + B *x = 0; + return *x; // should warn here! + } + +} diff --git a/test/Analysis/region-store.c b/test/Analysis/region-store.c new file mode 100644 index 000000000000..09c3f102e3ad --- /dev/null +++ b/test/Analysis/region-store.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s + +int printf(const char *restrict,...); + +// Testing core functionality of the region store. +// radar://10127782 +int compoundLiteralTest() { + int index = 0; + for (index = 0; index < 2; index++) { + int thing = (int []){0, 1}[index]; + printf("thing: %i\n", thing); + } + return 0; +} + +int compoundLiteralTest2() { + int index = 0; + for (index = 0; index < 3; index++) { + int thing = (int [][3]){{0,0,0}, {1,1,1}, {2,2,2}}[index][index]; + printf("thing: %i\n", thing); + } + return 0; +} diff --git a/test/Analysis/retain-release-path-notes-gc.m b/test/Analysis/retain-release-path-notes-gc.m index 1e74f003e1a7..feee525b85a3 100644 --- a/test/Analysis/retain-release-path-notes-gc.m +++ b/test/Analysis/retain-release-path-notes-gc.m @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -fobjc-gc-only -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=text -verify %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=plist-multi-file %s -o - | FileCheck %s /*** This file is for testing the path-sensitive notes for retain/release errors. @@ -71,3 +72,1339 @@ void retainReleaseIgnored () { } @end + +// CHECK: <?xml version="1.0" encoding="UTF-8"?> +// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +// CHECK: <plist version="1.0"> +// CHECK: <dict> +// CHECK: <key>files</key> +// CHECK: <array> +// CHECK: <string>{{.*}}retain-release-path-notes-gc.m</string> +// CHECK: </array> +// CHECK: <key>diagnostics</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>40</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK: <key>message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>42</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>43</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>43</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>43</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>43</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>43</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into 'leaked'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak of object when using garbage collection</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>creationViaCFCreate</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>43</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>col</key><integer>40</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK: <key>message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>47</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>17</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Reference count incremented. The object now has a +2 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Reference count incremented. The object now has a +2 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>48</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>49</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>49</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>49</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>49</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>49</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>49</integer> +// CHECK: <key>col</key><integer>21</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>49</integer> +// CHECK: <key>col</key><integer>26</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>In GC mode a call to 'CFMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. An object must have a 0 retain count to be garbage collected. After this call its retain count is +1</string> +// CHECK: <key>message</key> +// CHECK: <string>In GC mode a call to 'CFMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. An object must have a 0 retain count to be garbage collected. After this call its retain count is +1</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>49</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>49</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>21</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>26</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>In GC mode a call to 'NSMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. Since it now has a 0 retain count the object can be automatically collected by the garbage collector</string> +// CHECK: <key>message</key> +// CHECK: <string>In GC mode a call to 'NSMakeCollectable' decrements an object's retain count and registers the object with the garbage collector. Since it now has a 0 retain count the object can be automatically collected by the garbage collector</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>17</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Reference count incremented. The object now has a +1 retain count. The object is not eligible for garbage collection until the retain count reaches 0 again</string> +// CHECK: <key>message</key> +// CHECK: <string>Reference count incremented. The object now has a +1 retain count. The object is not eligible for garbage collection until the retain count reaches 0 again</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into 'leaked'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak of object when using garbage collection</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>makeCollectable</string> +// CHECK: <key>issue_hash</key><integer>6</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>52</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>37</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Method returns an Objective-C object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Method returns an Objective-C object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>17</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>In GC mode the 'retain' message has no effect</string> +// CHECK: <key>message</key> +// CHECK: <string>In GC mode the 'retain' message has no effect</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>In GC mode the 'release' message has no effect</string> +// CHECK: <key>message</key> +// CHECK: <string>In GC mode the 'release' message has no effect</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>In GC mode an 'autorelease' has no effect</string> +// CHECK: <key>message</key> +// CHECK: <string>In GC mode an 'autorelease' has no effect</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>60</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>60</integer> +// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>60</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>60</integer> +// CHECK: <key>col</key><integer>13</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>60</integer> +// CHECK: <key>col</key><integer>29</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Bad release</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>retainReleaseIgnored</string> +// CHECK: <key>issue_hash</key><integer>5</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>60</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>36</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK: <key>message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>36</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> +// CHECK: <key>message</key> +// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'object' and returned from method 'getViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'object' and returned from method 'getViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into 'object'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak of returned object when using garbage collection</string> +// CHECK: <key>issue_context_kind</key><string>Objective-C method</string> +// CHECK: <key>issue_context</key><string>getViolation</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>66</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>36</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK: <key>message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count. Core Foundation objects are not automatically garbage collected</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>36</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> +// CHECK: <key>message</key> +// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'object' and returned from method 'copyViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'object' and returned from method 'copyViolation' is potentially leaked when using garbage collection. Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak (when using garbage collection) of an object stored into 'object'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak of returned object when using garbage collection</string> +// CHECK: <key>issue_context_kind</key><string>Objective-C method</string> +// CHECK: <key>issue_context</key><string>copyViolation</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </plist> diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m index c3f5fcda4442..ebcfd6adf5d4 100644 --- a/test/Analysis/retain-release-path-notes.m +++ b/test/Analysis/retain-release-path-notes.m @@ -1,8 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -verify %s - -// This actually still works after the pseudo-object refactor, it just -// uses messages that say 'method' instead of 'property'. Ted wanted -// this xfailed and filed as a bug. rdar://problem/10402993 +// RN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=plist-multi-file %s -o - | FileCheck %s /*** This file is for testing the path-sensitive notes for retain/release errors. @@ -28,6 +25,9 @@ GC-specific notes should go in retain-release-path-notes-gc.m. @interface Foo : NSObject - (id)methodWithValue; @property(retain) id propertyValue; + +- (id)objectAtIndexedSubscript:(unsigned)index; +- (id)objectForKeyedSubscript:(id)key; @end typedef struct CFType *CFTypeRef; @@ -119,6 +119,16 @@ CFTypeRef CFGetRuleViolation () { return result; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object returned to caller with a +0 retain count}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} } +- (id)copyViolationIndexedSubscript { + id result = self[0]; // expected-note{{Subscript returns an Objective-C object with a +0 retain count}} + return result; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object returned to caller with a +0 retain count}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} +} + +- (id)copyViolationKeyedSubscript { + id result = self[self]; // expected-note{{Subscript returns an Objective-C object with a +0 retain count}} + return result; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object returned to caller with a +0 retain count}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} +} + - (id)getViolation { id result = [[Foo alloc] init]; // expected-warning{{leak}} expected-note{{Method returns an Objective-C object with a +1 retain count}} return result; // expected-note{{Object returned to caller as an owning reference (single retain count transferred to caller)}} expected-note{{Object leaked: object allocated and stored into 'result' is returned from a method whose name ('getViolation') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa}} @@ -130,3 +140,4474 @@ CFTypeRef CFGetRuleViolation () { return result; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} expected-note{{Object returned to caller with a +0 retain count}} expected-note{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} } @end + + +typedef unsigned long NSUInteger; + +@interface NSValue : NSObject +@end + +@interface NSNumber : NSValue ++ (NSNumber *)numberWithInt:(int)i; +@end + +@interface NSString : NSObject ++ (NSString *)stringWithUTF8String:(const char *)str; +@end + +@interface NSArray : NSObject ++ (NSArray *)arrayWithObjects:(const id [])objects count:(NSUInteger)count; +@end + +@interface NSDictionary : NSObject ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id /* <NSCopying> */ [])keys count:(NSUInteger)count; +@end + + +void testNumericLiteral() { + id result = @1; // expected-note{{NSNumber literal is an object with a +0 retain count}} + [result release]; // expected-warning{{decrement}} expected-note{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} + +void testBoxedInt(int x) { + id result = @(x); // expected-note{{NSNumber boxed expression produces an object with a +0 retain count}} + [result release]; // expected-warning{{decrement}} expected-note{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} + +void testBoxedString(const char *str) { + id result = @(str); // expected-note{{NSString boxed expression produces an object with a +0 retain count}} + [result release]; // expected-warning{{decrement}} expected-note{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} + +void testArray(id obj) { + id result = @[obj]; // expected-note{{NSArray literal is an object with a +0 retain count}} + [result release]; // expected-warning{{decrement}} expected-note{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} + +void testDictionary(id key, id value) { + id result = @{key: value}; // expected-note{{NSDictionary literal is an object with a +0 retain count}} + [result release]; // expected-warning{{decrement}} expected-note{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} +} + + +// CHECK: <?xml version="1.0" encoding="UTF-8"?> +// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +// CHECK: <plist version="1.0"> +// CHECK: <dict> +// CHECK: <key>files</key> +// CHECK: <array> +// CHECK: <string>{{.*}}retain-release-path-notes.m</string> +// CHECK: </array> +// CHECK: <key>diagnostics</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>37</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>45</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak of an object stored into 'leaked'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>creationViaAlloc</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>46</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>40</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>50</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak of an object stored into 'leaked'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>creationViaCFCreate</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>51</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>35</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Method returns an Objective-C object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Method returns an Objective-C object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>55</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>17</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Reference count incremented. The object now has a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Reference count incremented. The object now has a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>56</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>17</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Reference count incremented. The object now has a +2 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Reference count incremented. The object now has a +2 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>57</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Reference count decremented. The object now has a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Reference count decremented. The object now has a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>58</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak of an object stored into 'leaked'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>acquisitionViaMethod</string> +// CHECK: <key>issue_hash</key><integer>5</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>59</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Property returns an Objective-C object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Property returns an Objective-C object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>63</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>64</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>64</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>64</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>64</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>64</integer> +// CHECK: <key>col</key><integer>17</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>64</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>64</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Reference count incremented. The object now has a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Reference count incremented. The object now has a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>64</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>64</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak of an object stored into 'leaked'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>acquisitionViaProperty</string> +// CHECK: <key>issue_hash</key><integer>3</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>65</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>69</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>69</integer> +// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>69</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>69</integer> +// CHECK: <key>col</key><integer>35</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>69</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>69</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>69</integer> +// CHECK: <key>col</key><integer>37</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>69</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>69</integer> +// CHECK: <key>col</key><integer>35</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>12</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>17</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Reference count incremented. The object now has a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Reference count incremented. The object now has a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>70</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak of an object stored into 'leaked'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>acquisitionViaCFFunction</string> +// CHECK: <key>issue_hash</key><integer>3</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>71</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>37</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>75</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object released by directly sending the '-dealloc' message</string> +// CHECK: <key>message</key> +// CHECK: <string>Object released by directly sending the '-dealloc' message</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>76</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>77</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>77</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>77</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>77</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>77</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Reference-counted object is used after it is released</string> +// CHECK: <key>message</key> +// CHECK: <string>Reference-counted object is used after it is released</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Reference-counted object is used after it is released</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Use-after-release</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>explicitDealloc</string> +// CHECK: <key>issue_hash</key><integer>3</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>77</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>81</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>81</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>81</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>81</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>81</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>81</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>81</integer> +// CHECK: <key>col</key><integer>37</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>81</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>81</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>82</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>82</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>82</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>82</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>82</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>82</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>82</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object released</string> +// CHECK: <key>message</key> +// CHECK: <string>Object released</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>82</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>82</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>83</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>83</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>83</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>83</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>83</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Reference-counted object is used after it is released</string> +// CHECK: <key>message</key> +// CHECK: <string>Reference-counted object is used after it is released</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Reference-counted object is used after it is released</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Use-after-release</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>implicitDealloc</string> +// CHECK: <key>issue_hash</key><integer>3</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>83</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>87</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>87</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>87</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>87</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>87</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>87</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>87</integer> +// CHECK: <key>col</key><integer>37</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>87</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>87</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>88</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>88</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>88</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>88</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>88</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>88</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>88</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object sent -autorelease message</string> +// CHECK: <key>message</key> +// CHECK: <string>Object sent -autorelease message</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>88</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>88</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>89</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>89</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>89</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>89</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>89</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>89</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>89</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object sent -autorelease message</string> +// CHECK: <key>message</key> +// CHECK: <string>Object sent -autorelease message</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>89</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>89</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>90</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>90</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>90</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>90</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>90</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Object sent -autorelease too many times</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Object sent -autorelease too many times</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>overAutorelease</string> +// CHECK: <key>issue_hash</key><integer>4</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>90</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>94</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>94</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>94</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>94</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>94</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>94</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>94</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Property returns an Objective-C object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Property returns an Objective-C object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>94</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>94</integer> +// CHECK: <key>col</key><integer>31</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>95</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>95</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>95</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>95</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>95</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>95</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>95</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object sent -autorelease message</string> +// CHECK: <key>message</key> +// CHECK: <string>Object sent -autorelease message</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>95</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>95</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>96</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>96</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>96</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>96</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>96</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Object sent -autorelease too many times</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Object sent -autorelease too many times</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>autoreleaseUnowned</string> +// CHECK: <key>issue_hash</key><integer>3</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>96</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>100</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>100</integer> +// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>100</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>100</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>100</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>100</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>100</integer> +// CHECK: <key>col</key><integer>40</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>100</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>100</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>21</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>26</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>When GC is not enabled a call to 'CFMakeCollectable' has no effect on its argument</string> +// CHECK: <key>message</key> +// CHECK: <string>When GC is not enabled a call to 'CFMakeCollectable' has no effect on its argument</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>101</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>21</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>26</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>When GC is not enabled a call to 'NSMakeCollectable' has no effect on its argument</string> +// CHECK: <key>message</key> +// CHECK: <string>When GC is not enabled a call to 'NSMakeCollectable' has no effect on its argument</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>102</integer> +// CHECK: <key>col</key><integer>19</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>103</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>103</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>103</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>103</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>103</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'leaked' is not referenced later in this execution path and has a retain count of +1</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak of an object stored into 'leaked'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>makeCollectableIgnored</string> +// CHECK: <key>issue_hash</key><integer>4</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>103</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>107</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>107</integer> +// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>107</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>107</integer> +// CHECK: <key>col</key><integer>35</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>107</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>107</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>107</integer> +// CHECK: <key>col</key><integer>37</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Call to function 'CFGetSomething' returns a Core Foundation object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>107</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>107</integer> +// CHECK: <key>col</key><integer>35</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object returned to caller with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Object returned to caller with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: <key>message</key> +// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Method should return an owned object</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>CFCopyRuleViolation</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>108</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>112</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>112</integer> +// CHECK: <key>col</key><integer>11</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>112</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>112</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>112</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>112</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>112</integer> +// CHECK: <key>col</key><integer>40</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Call to function 'CFCreateSomething' returns a Core Foundation object with a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>112</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>112</integer> +// CHECK: <key>col</key><integer>38</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> +// CHECK: <key>message</key> +// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'object' is returned from a function whose name ('CFGetRuleViolation') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'object' is returned from a function whose name ('CFGetRuleViolation') does not contain 'Copy' or 'Create'. This violates the naming convention rules given in the Memory Management Guide for Core Foundation</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak of an object stored into 'object'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak of returned object</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>CFGetRuleViolation</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>113</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>32</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>32</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Property returns an Objective-C object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Property returns an Objective-C object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>118</integer> +// CHECK: <key>col</key><integer>32</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object returned to caller with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Object returned to caller with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: <key>message</key> +// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Method should return an owned object</string> +// CHECK: <key>issue_context_kind</key><string>Objective-C method</string> +// CHECK: <key>issue_context</key><string>copyViolation</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>119</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Subscript returns an Objective-C object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Subscript returns an Objective-C object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>123</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object returned to caller with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Object returned to caller with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: <key>message</key> +// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Method should return an owned object</string> +// CHECK: <key>issue_context_kind</key><string>Objective-C method</string> +// CHECK: <key>issue_context</key><string>copyViolationIndexedSubscript</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>124</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Subscript returns an Objective-C object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Subscript returns an Objective-C object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>128</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object returned to caller with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Object returned to caller with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: <key>message</key> +// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Method should return an owned object</string> +// CHECK: <key>issue_context_kind</key><string>Objective-C method</string> +// CHECK: <key>issue_context</key><string>copyViolationKeyedSubscript</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>129</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>133</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>133</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>133</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>133</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>133</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>133</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>133</integer> +// CHECK: <key>col</key><integer>32</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>133</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>133</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> +// CHECK: <key>message</key> +// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'result' is returned from a method whose name ('getViolation') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa</string> +// CHECK: <key>message</key> +// CHECK: <string>Object leaked: object allocated and stored into 'result' is returned from a method whose name ('getViolation') does not start with 'copy', 'mutableCopy', 'alloc' or 'new'. This violates the naming convention rules given in the Memory Management Guide for Cocoa</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Potential leak of an object stored into 'result'</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Leak of returned object</string> +// CHECK: <key>issue_context_kind</key><string>Objective-C method</string> +// CHECK: <key>issue_context</key><string>getViolation</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>134</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>138</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>138</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>138</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>138</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>138</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>138</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>138</integer> +// CHECK: <key>col</key><integer>32</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>138</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>138</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>139</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>139</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>139</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>139</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>139</integer> +// CHECK: <key>col</key><integer>22</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>139</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>139</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object sent -autorelease message</string> +// CHECK: <key>message</key> +// CHECK: <string>Object sent -autorelease message</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>139</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>139</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>10</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object returned to caller with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>Object returned to caller with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: <key>message</key> +// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Method should return an owned object</string> +// CHECK: <key>issue_context_kind</key><string>Objective-C method</string> +// CHECK: <key>issue_context</key><string>copyAutorelease</string> +// CHECK: <key>issue_hash</key><integer>3</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>140</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>16</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>NSNumber literal is an object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>NSNumber literal is an object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>168</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>169</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>169</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>169</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>169</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>169</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Bad release</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>testNumericLiteral</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>169</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>173</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>173</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>173</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>173</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>173</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>173</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>173</integer> +// CHECK: <key>col</key><integer>18</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>NSNumber boxed expression produces an object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>NSNumber boxed expression produces an object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>173</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>173</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>174</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>174</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>174</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>174</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>174</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Bad release</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>testBoxedInt</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>174</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>178</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>178</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>178</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>178</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>178</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>178</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>178</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>NSString boxed expression produces an object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>NSString boxed expression produces an object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>178</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>178</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>179</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>179</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>179</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>179</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>179</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Bad release</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>testBoxedString</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>179</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>183</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>183</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>183</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>183</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>183</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>183</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>183</integer> +// CHECK: <key>col</key><integer>20</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>NSArray literal is an object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>NSArray literal is an object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>183</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>183</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>184</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>184</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>184</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>184</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>184</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Bad release</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>testArray</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>184</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>path</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>188</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>188</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>188</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>188</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>188</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>188</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>188</integer> +// CHECK: <key>col</key><integer>27</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>NSDictionary literal is an object with a +0 retain count</string> +// CHECK: <key>message</key> +// CHECK: <string>NSDictionary literal is an object with a +0 retain count</string> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>188</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>188</integer> +// CHECK: <key>col</key><integer>15</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>189</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>189</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>kind</key><string>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>189</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <key>ranges</key> +// CHECK: <array> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>line</key><integer>189</integer> +// CHECK: <key>col</key><integer>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: <dict> +// CHECK: <key>line</key><integer>189</integer> +// CHECK: <key>col</key><integer>9</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>depth</key><integer>0</integer> +// CHECK: <key>extended_message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>message</key> +// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string> +// CHECK: <key>category</key><string>Memory (Core Foundation/Objective-C)</string> +// CHECK: <key>type</key><string>Bad release</string> +// CHECK: <key>issue_context_kind</key><string>function</string> +// CHECK: <key>issue_context</key><string>testDictionary</string> +// CHECK: <key>issue_hash</key><integer>2</integer> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>189</integer> +// CHECK: <key>col</key><integer>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </dict> +// CHECK: </plist> diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 06c510e5dd3e..ba492b7b19a7 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -142,9 +142,13 @@ NSFastEnumerationState; @end @class NSString, NSDictionary; @interface NSValue : NSObject <NSCopying, NSCoding> - (void)getValue:(void *)value; -@end @interface NSNumber : NSValue - (char)charValue; +@end +@interface NSNumber : NSValue +- (char)charValue; - (id)initWithInt:(int)value; -@end @class NSString; ++ (NSNumber *)numberWithInt:(int)value; +@end +@class NSString; @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration> - (NSUInteger)count; - (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt; @@ -195,7 +199,7 @@ typedef struct IONotificationPort * IONotificationPortRef; typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator ); io_service_t IOServiceGetMatchingService( mach_port_t masterPort, CFDictionaryRef matching ); kern_return_t IOServiceGetMatchingServices( mach_port_t masterPort, CFDictionaryRef matching, io_iterator_t * existing ); -kern_return_t IOServiceAddNotification( mach_port_t masterPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); +kern_return_t IOServiceAddNotification( mach_port_t masterPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); // expected-note {{'IOServiceAddNotification' declared here}} kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification ); CFMutableDictionaryRef IOServiceMatching( const char * name ); CFMutableDictionaryRef IOServiceNameMatching( const char * name ); @@ -222,8 +226,10 @@ typedef struct CGLayer *CGLayerRef; @end @protocol NSValidatedUserInterfaceItem - (SEL)action; @end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem; @end @class NSDate, NSDictionary, NSError, NSException, NSNotification; +@class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; @interface NSApplication : NSResponder <NSUserInterfaceValidations> { } +- (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo; @end enum { NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; typedef NSUInteger NSApplicationTerminateReply; @@ -231,7 +237,7 @@ typedef NSUInteger NSApplicationTerminateReply; @end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; @interface NSCell : NSObject <NSCopying, NSCoding> { } -@end @class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; +@end typedef struct { } CVTimeStamp; @@ -294,6 +300,9 @@ extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); + (id)array; @end +// This is how NSMakeCollectable is declared in the OS X 10.8 headers. +id NSMakeCollectable(CFTypeRef __attribute__((cf_consumed))) __attribute__((ns_returns_retained)); + //===----------------------------------------------------------------------===// // Test cases. @@ -747,7 +756,7 @@ typedef CFTypeRef OtherRef; @end //===----------------------------------------------------------------------===// -//<rdar://problem/6320065> false positive - init method returns an object +// <rdar://problem/6320065> false positive - init method returns an object // owned by caller //===----------------------------------------------------------------------===// @@ -1055,10 +1064,14 @@ typedef struct _opaque_pthread_t *__darwin_pthread_t; typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t; typedef __darwin_pthread_t pthread_t; typedef __darwin_pthread_attr_t pthread_attr_t; +typedef unsigned long __darwin_pthread_key_t; +typedef __darwin_pthread_key_t pthread_key_t; int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *); +int pthread_setspecific(pthread_key_t key, const void *value); + void *rdar_7299394_start_routine(void *p) { [((id) p) release]; return 0; @@ -1072,6 +1085,16 @@ void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { } //===----------------------------------------------------------------------===// +// <rdar://problem/11282706> false positive with not understanding thread +// local storage +//===----------------------------------------------------------------------===// + +void rdar11282706(pthread_key_t key) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + pthread_setspecific(key, (void*) number); +} + +//===----------------------------------------------------------------------===// // <rdar://problem/7283567> False leak associated with call to // CVPixelBufferCreateWithBytes () // @@ -1291,6 +1314,11 @@ void testattr2_b() { TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // expected-warning{{leak}} } +void testattr2_b_11358224_self_assign_looses_the_leak() { + TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit];// expected-warning{{leak}} + x = x; +} + void testattr2_c() { TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // no-warning [x release]; @@ -1427,8 +1455,7 @@ void test_blocks_1_indirect_release_via_call(void) { } void test_blocks_1_indirect_retain_via_call(void) { - // Eventually this should be reported as a leak. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning {{leak}} ^(NSObject *o){ [o retain]; }(number); } @@ -1667,6 +1694,58 @@ void rdar_10824732() { } } +// Stop tracking objects passed to functions, which take callbacks as parameters. +// radar://10973977 +typedef int (*CloseCallback) (void *); +void ReaderForIO(CloseCallback ioclose, void *ioctx); +int IOClose(void *context); + +@protocol SInS <NSObject> +@end + +@interface radar10973977 : NSObject +- (id<SInS>)inputS; +- (void)reader; +@end + +@implementation radar10973977 +- (void)reader +{ + id<SInS> inputS = [[self inputS] retain]; + ReaderForIO(IOClose, inputS); +} +- (id<SInS>)inputS +{ + return 0; +} +@end + +// Object escapes through a selector callback: radar://11398514 +extern id NSApp; +@interface MySheetController +- (id<SInS>)inputS; +- (void)showDoSomethingSheetAction:(id)action; +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; +@end + +@implementation MySheetController +- (id<SInS>)inputS { + return 0; +} +- (void)showDoSomethingSheetAction:(id)action { + id<SInS> inputS = [[self inputS] retain]; + [NSApp beginSheet:0 + modalForWindow:0 + modalDelegate:0 + didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo:(void *)inputS]; // no - warning +} +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { + + id contextObject = (id)contextInfo; + [contextObject release]; +} +@end //===----------------------------------------------------------------------===// // Test returning allocated memory in a struct. // @@ -1739,3 +1818,40 @@ void test_objc_arrays() { } } +void test_objc_integer_literals() { + id value = [@1 retain]; // expected-warning {{leak}} + [value description]; +} + +void test_objc_boxed_expressions(int x, const char *y) { + id value = [@(x) retain]; // expected-warning {{leak}} + [value description]; + + value = [@(y) retain]; // expected-warning {{leak}} + [value description]; +} + +// Test NSLog doesn't escape tracked objects. +void rdar11400885(int y) +{ + @autoreleasepool { + NSString *printString; + if(y > 2) + printString = [[NSString alloc] init]; + else + printString = [[NSString alloc] init]; + NSLog(@"Once %@", printString); + [printString release]; + NSLog(@"Again: %@", printString); // expected-warning {{Reference-counted object is used after it is released}} + } +} + +id makeCollectableNonLeak() { + extern CFTypeRef CFCreateSomething(); + + CFTypeRef object = CFCreateSomething(); // +1 + CFRetain(object); // +2 + id objCObject = NSMakeCollectable(object); // +2 + [objCObject release]; // +1 + return [objCObject autorelease]; // +0 +} diff --git a/test/Analysis/self-init.m b/test/Analysis/self-init.m index d5151733430d..b0c51a2b37e1 100644 --- a/test/Analysis/self-init.m +++ b/test/Analysis/self-init.m @@ -1,7 +1,9 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties %s -verify +// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties -analyzer-ipa=dynamic -fno-builtin %s -verify +// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties -fno-builtin %s -verify @class NSZone, NSCoder; -@protocol NSObject- (id)self; +@protocol NSObject +- (id)self; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end @@ -254,3 +256,28 @@ extern id _commonInit(MyObj *self); return self; } @end + +// Test for radar://11125870: init constructing a special instance. +typedef signed char BOOL; +@interface MyClass : NSObject +@end +@implementation MyClass ++ (id)specialInstance { + return [[MyClass alloc] init]; +} +- (id)initSpecially:(BOOL)handleSpecially { + if ((self = [super init])) { + if (handleSpecially) { + self = [MyClass specialInstance]; + } + } + return self; +} +- (id)initSelfSelf { + if ((self = [super init])) { + self = self; + } + return self; +} +@end + diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp index b09e43560830..b21a03dc38a4 100644 --- a/test/Analysis/stack-addr-ps.cpp +++ b/test/Analysis/stack-addr-ps.cpp @@ -84,3 +84,9 @@ struct TS { return x; } }; + +// rdar://11345441 +int* f5() { + int& i = i; // expected-warning {{Assigned value is garbage or undefined}} expected-note {{binding reference variable 'i' here}} + return &i; // expected-warning {{address of stack memory associated with local variable 'i' returned}} +} diff --git a/test/Analysis/string-fail.c b/test/Analysis/string-fail.c index 3bff6d40dd51..ac5c6d057235 100644 --- a/test/Analysis/string-fail.c +++ b/test/Analysis/string-fail.c @@ -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}} } diff --git a/test/Analysis/string.c b/test/Analysis/string.c index c0814b89c17c..32f5db3a9a43 100644 --- a/test/Analysis/string.c +++ b/test/Analysis/string.c @@ -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,18 @@ 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) { + char dst[] = "123"; + strncpy(dst, src, 0); // no-warning +} + +void strncpy_empty() { + char dst[] = "123"; + char src[] = ""; + strncpy(dst, src, 4); // no-warning } //===----------------------------------------------------------------------=== @@ -617,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) { @@ -661,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}} @@ -678,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}} @@ -692,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) { @@ -716,6 +673,17 @@ void strncat_too_big(char *dst, char *src) { strncat(dst, src, 2); // expected-warning{{This expression will create a string whose length is too big to be represented as a size_t}} } +void strncat_zero(char *src) { + char dst[] = "123"; + strncat(dst, src, 0); // no-warning +} + +void strncat_empty() { + char dst[8] = "123"; + char src[] = ""; + strncat(dst, src, 4); // no-warning +} + //===----------------------------------------------------------------------=== // strcmp() //===----------------------------------------------------------------------=== @@ -724,41 +692,35 @@ void strncat_too_big(char *dst, char *src) { 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() { @@ -776,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}} } //===----------------------------------------------------------------------=== @@ -819,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() { @@ -871,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}} } //===----------------------------------------------------------------------=== @@ -930,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() { @@ -982,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}} } //===----------------------------------------------------------------------=== @@ -1020,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() { @@ -1072,53 +997,45 @@ 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}} } diff --git a/test/Analysis/svalbuilder-logic.c b/test/Analysis/svalbuilder-logic.c new file mode 100644 index 000000000000..bc79f859053c --- /dev/null +++ b/test/Analysis/svalbuilder-logic.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s + +// Testing core functionality of the SValBuilder. + +int SValBuilderLogicNoCrash(int *x) { + return 3 - (int)(x +3); +} diff --git a/test/Analysis/system-header-simulator-objc.h b/test/Analysis/system-header-simulator-objc.h index 92d5899abf8d..a647b3740406 100644 --- a/test/Analysis/system-header-simulator-objc.h +++ b/test/Analysis/system-header-simulator-objc.h @@ -85,7 +85,13 @@ typedef double NSTimeInterval; - (id)initWithBytes:(const void *)bytes length:(NSUInteger)len encoding:(NSStringEncoding)encoding; - (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)len encoding:(NSStringEncoding)encoding freeWhenDone:(BOOL)freeBuffer; + (id)stringWithUTF8String:(const char *)nullTerminatedCString; ++ (id)stringWithString:(NSString *)string; @end @class NSString, NSURL, NSError; + +@interface NSMutableString : NSString +- (void)appendFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2))); +@end + @interface NSData : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; + (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; + (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; @@ -112,3 +118,13 @@ extern void CFRelease(CFTypeRef cf); extern CFMutableStringRef CFStringCreateMutableWithExternalCharactersNoCopy(CFAllocatorRef alloc, UniChar *chars, CFIndex numChars, CFIndex capacity, CFAllocatorRef externalCharactersAllocator); extern CFStringRef CFStringCreateWithCStringNoCopy(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding, CFAllocatorRef contentsDeallocator); extern void CFStringAppend(CFMutableStringRef theString, CFStringRef appendedString); + +void SystemHeaderFunctionWithBlockParam(void *, void (^block)(void *), unsigned); + +@interface NSPointerArray : NSObject <NSFastEnumeration, NSCopying, NSCoding> +- (void)addPointer:(void *)pointer; +- (void)insertPointer:(void *)item atIndex:(NSUInteger)index; +- (void)replacePointerAtIndex:(NSUInteger)index withPointer:(void *)item; +- (void *)pointerAtIndex:(NSUInteger)index; +@end + diff --git a/test/Analysis/system-header-simulator.h b/test/Analysis/system-header-simulator.h index 6212131071de..5790fb9cff4a 100644 --- a/test/Analysis/system-header-simulator.h +++ b/test/Analysis/system-header-simulator.h @@ -36,3 +36,27 @@ FILE *funopen(const void *, fpos_t (*)(void *, fpos_t, int), int (*)(void *)); +int sqlite3_bind_text_my(int, const char*, int n, void(*)(void*)); + +typedef void (*freeCallback) (void*); +typedef struct { + int i; + freeCallback fc; +} StWithCallback; + +int dealocateMemWhenDoneByVal(void*, StWithCallback); +int dealocateMemWhenDoneByRef(StWithCallback*, const void*); + +typedef struct CGContext *CGContextRef; +CGContextRef CGBitmapContextCreate(void *data/*, size_t width, size_t height, + size_t bitsPerComponent, size_t bytesPerRow, + CGColorSpaceRef space, + CGBitmapInfo bitmapInfo*/); +void *CGBitmapContextGetData(CGContextRef context); + +// Include xpc. +typedef struct _xpc_connection_s * xpc_connection_t; +typedef void (*xpc_finalizer_t)(void *value); +void xpc_connection_set_context(xpc_connection_t connection, void *context); +void xpc_connection_set_finalizer_f(xpc_connection_t connection, xpc_finalizer_t finalizer); +void xpc_connection_resume(xpc_connection_t connection); diff --git a/test/Analysis/taint-generic.c b/test/Analysis/taint-generic.c index b00372a3ffbd..8ee1896e96e9 100644 --- a/test/Analysis/taint-generic.c +++ b/test/Analysis/taint-generic.c @@ -183,3 +183,32 @@ void testTaintedVLASize() { scanf("%d", &x); int vla[x]; // expected-warning{{Declared variable-length array (VLA) has tainted size}} } + +// This computation used to take a very long time. +#define longcmp(a,b,c) { \ + a -= c; a ^= c; c += b; b -= a; b ^= (a<<6) | (a >> (32-b)); a += c; c -= b; c ^= b; b += a; \ + a -= c; a ^= c; c += b; b -= a; b ^= a; a += c; c -= b; c ^= b; b += a; } + +unsigned radar11369570_hanging(const unsigned char *arr, int l) { + unsigned a, b, c; + a = b = c = 0x9899e3 + l; + while (l >= 6) { + unsigned t; + scanf("%d", &t); + a += b; + a ^= a; + a += (arr[3] + ((unsigned) arr[2] << 8) + ((unsigned) arr[1] << 16) + ((unsigned) arr[0] << 24)); + longcmp(a, t, c); + l -= 12; + } + return 5/a; // expected-warning {{Division by a tainted value, possibly zero}} +} + +// Check that we do not assert of the following code. +int SymSymExprWithDiffTypes(void* p) { + int i; + scanf("%d", &i); + int j = (i % (int)(long)p); + return 5/j; // expected-warning {{Division by a tainted value, possibly zero}} +} + diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c index 377333505e18..a83ee32baca8 100644 --- a/test/Analysis/taint-tester.c +++ b/test/Analysis/taint-tester.c @@ -40,7 +40,7 @@ void taintTracking(int x) { // FIXME: We fail to propagate the taint here because RegionStore does not // handle ElementRegions with symbolic indexes. int addrDeref = *addr; // expected-warning + {{tainted}} - int _addrDeref = addrDeref; + int _addrDeref = addrDeref; // expected-warning + {{tainted}} // Tainted struct address, casts. struct XYStruct *xyPtr = 0; diff --git a/test/Analysis/temp-obj-dtors-cfg-output.cpp b/test/Analysis/temp-obj-dtors-cfg-output.cpp index 53ab211615c3..6dbbc821bbbb 100644 --- a/test/Analysis/temp-obj-dtors-cfg-output.cpp +++ b/test/Analysis/temp-obj-dtors-cfg-output.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -cfg-add-implicit-dtors -cfg-add-initializers %s 2>&1 | FileCheck %s +// RUN: rm -f %t +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -cfg-add-implicit-dtors %s > %t 2>&1 +// RUN: FileCheck --input-file=%t %s // XPASS: * class A { @@ -106,9 +108,88 @@ TestCtorInits::TestCtorInits() : a(int(A()) + int(B())) , b() {} +// CHECK: [B1 (ENTRY)] +// CHECK: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK: Preds (1): B1 +// CHECK: [B1 (ENTRY)] +// CHECK: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK: Preds (1): B1 +// CHECK: [B2 (ENTRY)] +// CHECK: Succs (1): B1 +// CHECK: [B1] +// CHECK: 1: A() (CXXConstructExpr, class A) +// CHECK: 2: [B1.1] (BindTemporary) +// CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) +// CHECK: 4: [B1.3] +// CHECK: 5: [B1.4] (CXXConstructExpr, class A) +// CHECK: 6: ~A() (Temporary object destructor) +// CHECK: 7: return [B1.5]; +// CHECK: Preds (1): B2 +// CHECK: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK: Preds (1): B1 +// CHECK: [B2 (ENTRY)] +// CHECK: Succs (1): B1 +// CHECK: [B1] +// CHECK: 1: false +// CHECK: 2: return [B1.1]; +// CHECK: Preds (1): B2 +// CHECK: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK: Preds (1): B1 +// CHECK: [B2 (ENTRY)] +// CHECK: Succs (1): B1 +// CHECK: [B1] +// CHECK: 1: 0 +// CHECK: 2: return [B1.1]; +// CHECK: Preds (1): B2 +// CHECK: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK: Preds (1): B1 +// CHECK: [B1 (ENTRY)] +// CHECK: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK: Preds (1): B1 +// CHECK: [B1 (ENTRY)] +// CHECK: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK: Preds (1): B1 +// CHECK: [B2 (ENTRY)] +// CHECK: Succs (1): B1 +// CHECK: [B1] +// CHECK: 1: true +// CHECK: 2: return [B1.1]; +// CHECK: Preds (1): B2 +// CHECK: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK: Preds (1): B1 +// CHECK: [B2 (ENTRY)] +// CHECK: Succs (1): B1 +// CHECK: [B1] +// CHECK: 1: 1 +// CHECK: 2: return [B1.1]; +// CHECK: Preds (1): B2 +// CHECK: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK: Preds (1): B1 +// CHECK: [B2 (ENTRY)] +// CHECK: Succs (1): B1 +// CHECK: [B1] +// CHECK: 1: A() (CXXConstructExpr, class A) +// CHECK: 2: [B1.1] (BindTemporary) +// CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) +// CHECK: 4: [B1.3] +// CHECK: 5: [B1.4] (CXXConstructExpr, class A) +// CHECK: 6: ~A() (Temporary object destructor) +// CHECK: 7: return [B1.5]; +// CHECK: Preds (1): B2 +// CHECK: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK: Preds (1): B1 // CHECK: [B2 (ENTRY)] // CHECK: Succs (1): B1 - // CHECK: [B1] // CHECK: 1: A() (CXXConstructExpr, class A) // CHECK: 2: [B1.1] (BindTemporary) @@ -150,7 +231,7 @@ TestCtorInits::TestCtorInits() // CHECK: [B0 (EXIT)] // CHECK: Preds (1): B1 // CHECK: [B10 (ENTRY)] -// CHECK: Succs (1): B8 +// CHECK: Succs (1): B9 // CHECK: [B1] // CHECK: 1: ~A() (Temporary object destructor) // CHECK: 2: int b; @@ -161,62 +242,62 @@ TestCtorInits::TestCtorInits() // CHECK: Preds (1): B3 // CHECK: Succs (1): B1 // CHECK: [B3] -// CHECK: 1: [B4.6] && [B5.5] +// CHECK: 1: [B5.6] && [B4.5] // CHECK: 2: foo // CHECK: 3: [B3.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool)) // CHECK: 4: [B3.3]([B3.1]) -// CHECK: T: [B4.6] && ... -// CHECK: Preds (2): B5 B4 +// CHECK: T: [B5.6] && ... +// CHECK: Preds (2): B4 B5 // CHECK: Succs (2): B2 B1 // CHECK: [B4] +// CHECK: 1: B() (CXXConstructExpr, class B) +// CHECK: 2: [B4.1] (BindTemporary) +// CHECK: 3: [B4.2].operator _Bool +// CHECK: 4: [B4.3]() +// CHECK: 5: [B4.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CHECK: Preds (1): B5 +// CHECK: Succs (1): B3 +// CHECK: [B5] // CHECK: 1: ~A() (Temporary object destructor) // CHECK: 2: A() (CXXConstructExpr, class A) -// CHECK: 3: [B4.2] (BindTemporary) -// CHECK: 4: [B4.3].operator _Bool -// CHECK: 5: [B4.4]() -// CHECK: 6: [B4.5] (ImplicitCastExpr, UserDefinedConversion, _Bool) -// CHECK: T: [B4.6] && ... +// CHECK: 3: [B5.2] (BindTemporary) +// CHECK: 4: [B5.3].operator _Bool +// CHECK: 5: [B5.4]() +// CHECK: 6: [B5.5] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CHECK: T: [B5.6] && ... // CHECK: Preds (2): B6 B7 -// CHECK: Succs (2): B5 B3 -// CHECK: [B5] -// CHECK: 1: B() (CXXConstructExpr, class B) -// CHECK: 2: [B5.1] (BindTemporary) -// CHECK: 3: [B5.2].operator _Bool -// CHECK: 4: [B5.3]() -// CHECK: 5: [B5.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) -// CHECK: Preds (1): B4 -// CHECK: Succs (1): B3 +// CHECK: Succs (2): B4 B3 // CHECK: [B6] // CHECK: 1: ~B() (Temporary object destructor) // CHECK: Preds (1): B7 -// CHECK: Succs (1): B4 +// CHECK: Succs (1): B5 // CHECK: [B7] -// CHECK: 1: [B8.5] && [B9.5] +// CHECK: 1: [B9.5] && [B8.5] // CHECK: 2: bool a = A().operator _Bool() && B().operator _Bool(); -// CHECK: T: [B8.5] && ... -// CHECK: Preds (2): B9 B8 -// CHECK: Succs (2): B6 B4 +// CHECK: T: [B9.5] && ... +// CHECK: Preds (2): B8 B9 +// CHECK: Succs (2): B6 B5 // CHECK: [B8] -// CHECK: 1: A() (CXXConstructExpr, class A) +// CHECK: 1: B() (CXXConstructExpr, class B) // CHECK: 2: [B8.1] (BindTemporary) // CHECK: 3: [B8.2].operator _Bool // CHECK: 4: [B8.3]() // CHECK: 5: [B8.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) -// CHECK: T: [B8.5] && ... -// CHECK: Preds (1): B10 -// CHECK: Succs (2): B9 B7 +// CHECK: Preds (1): B9 +// CHECK: Succs (1): B7 // CHECK: [B9] -// CHECK: 1: B() (CXXConstructExpr, class B) +// CHECK: 1: A() (CXXConstructExpr, class A) // CHECK: 2: [B9.1] (BindTemporary) // CHECK: 3: [B9.2].operator _Bool // CHECK: 4: [B9.3]() // CHECK: 5: [B9.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) -// CHECK: Preds (1): B8 -// CHECK: Succs (1): B7 +// CHECK: T: [B9.5] && ... +// CHECK: Preds (1): B10 +// CHECK: Succs (2): B8 B7 // CHECK: [B0 (EXIT)] // CHECK: Preds (1): B1 // CHECK: [B10 (ENTRY)] -// CHECK: Succs (1): B8 +// CHECK: Succs (1): B9 // CHECK: [B1] // CHECK: 1: ~A() (Temporary object destructor) // CHECK: 2: int b; @@ -227,58 +308,58 @@ TestCtorInits::TestCtorInits() // CHECK: Preds (1): B3 // CHECK: Succs (1): B1 // CHECK: [B3] -// CHECK: 1: [B4.6] || [B5.5] +// CHECK: 1: [B5.6] || [B4.5] // CHECK: 2: foo // CHECK: 3: [B3.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool)) // CHECK: 4: [B3.3]([B3.1]) -// CHECK: T: [B4.6] || ... -// CHECK: Preds (2): B5 B4 +// CHECK: T: [B5.6] || ... +// CHECK: Preds (2): B4 B5 // CHECK: Succs (2): B1 B2 // CHECK: [B4] +// CHECK: 1: B() (CXXConstructExpr, class B) +// CHECK: 2: [B4.1] (BindTemporary) +// CHECK: 3: [B4.2].operator _Bool +// CHECK: 4: [B4.3]() +// CHECK: 5: [B4.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CHECK: Preds (1): B5 +// CHECK: Succs (1): B3 +// CHECK: [B5] // CHECK: 1: ~A() (Temporary object destructor) // CHECK: 2: A() (CXXConstructExpr, class A) -// CHECK: 3: [B4.2] (BindTemporary) -// CHECK: 4: [B4.3].operator _Bool -// CHECK: 5: [B4.4]() -// CHECK: 6: [B4.5] (ImplicitCastExpr, UserDefinedConversion, _Bool) -// CHECK: T: [B4.6] || ... +// CHECK: 3: [B5.2] (BindTemporary) +// CHECK: 4: [B5.3].operator _Bool +// CHECK: 5: [B5.4]() +// CHECK: 6: [B5.5] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CHECK: T: [B5.6] || ... // CHECK: Preds (2): B6 B7 -// CHECK: Succs (2): B3 B5 -// CHECK: [B5] -// CHECK: 1: B() (CXXConstructExpr, class B) -// CHECK: 2: [B5.1] (BindTemporary) -// CHECK: 3: [B5.2].operator _Bool -// CHECK: 4: [B5.3]() -// CHECK: 5: [B5.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) -// CHECK: Preds (1): B4 -// CHECK: Succs (1): B3 +// CHECK: Succs (2): B3 B4 // CHECK: [B6] // CHECK: 1: ~B() (Temporary object destructor) // CHECK: Preds (1): B7 -// CHECK: Succs (1): B4 +// CHECK: Succs (1): B5 // CHECK: [B7] -// CHECK: 1: [B8.5] || [B9.5] +// CHECK: 1: [B9.5] || [B8.5] // CHECK: 2: bool a = A().operator _Bool() || B().operator _Bool(); -// CHECK: T: [B8.5] || ... -// CHECK: Preds (2): B9 B8 -// CHECK: Succs (2): B4 B6 +// CHECK: T: [B9.5] || ... +// CHECK: Preds (2): B8 B9 +// CHECK: Succs (2): B5 B6 // CHECK: [B8] -// CHECK: 1: A() (CXXConstructExpr, class A) +// CHECK: 1: B() (CXXConstructExpr, class B) // CHECK: 2: [B8.1] (BindTemporary) // CHECK: 3: [B8.2].operator _Bool // CHECK: 4: [B8.3]() // CHECK: 5: [B8.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) -// CHECK: T: [B8.5] || ... -// CHECK: Preds (1): B10 -// CHECK: Succs (2): B7 B9 +// CHECK: Preds (1): B9 +// CHECK: Succs (1): B7 // CHECK: [B9] -// CHECK: 1: B() (CXXConstructExpr, class B) +// CHECK: 1: A() (CXXConstructExpr, class A) // CHECK: 2: [B9.1] (BindTemporary) // CHECK: 3: [B9.2].operator _Bool // CHECK: 4: [B9.3]() // CHECK: 5: [B9.4] (ImplicitCastExpr, UserDefinedConversion, _Bool) -// CHECK: Preds (1): B8 -// CHECK: Succs (1): B7 +// CHECK: T: [B9.5] || ... +// CHECK: Preds (1): B10 +// CHECK: Succs (2): B7 B8 // CHECK: [B0 (EXIT)] // CHECK: Preds (1): B1 // CHECK: [B11 (ENTRY)] diff --git a/test/Analysis/templates.cpp b/test/Analysis/templates.cpp new file mode 100644 index 000000000000..671aa7858204 --- /dev/null +++ b/test/Analysis/templates.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fblocks -verify %s + +void clang_analyzer_eval(bool); + +// Do not crash on this templated code which uses a block. +typedef void (^my_block)(void); +static void useBlock(my_block block){} +template<class T> class MyClass; +typedef MyClass<float> Mf; + +template<class T> +class MyClass +{ +public: + MyClass() {} + MyClass(T a); + void I(); +private: + static const T one; +}; + +template<class T> const T MyClass<T>::one = static_cast<T>(1); +template<class T> inline MyClass<T>::MyClass(T a){} +template<class T> void MyClass<T>::I() { + static MyClass<T>* mPtr = 0; + useBlock(^{ mPtr = new MyClass<T> (MyClass<T>::one); }); +}; +int main(){ + Mf m; + m.I(); +} + + +// <rdar://problem/11949235> +template<class T, unsigned N> +inline unsigned array_lengthof(T (&)[N]) { + return N; +} + +void testNonTypeTemplateInstantiation() { + const char *S[] = { "a", "b" }; + clang_analyzer_eval(array_lengthof(S) == 2); // expected-warning{{TRUE}} +} + diff --git a/test/Analysis/test-variably-modified-types.c b/test/Analysis/test-variably-modified-types.c new file mode 100644 index 000000000000..a833434228d1 --- /dev/null +++ b/test/Analysis/test-variably-modified-types.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyze-function=testVariablyModifiedTypes -verify %s + +// Test that we process variably modified type correctly - the call graph construction should pick up function_with_bug while recursively visiting test_variably_modifiable_types. +unsigned getArraySize(int *x) { + if (!x) + return *x; // expected-warning {{Dereference of null pointer}} + return 1; +} + +int testVariablyModifiedTypes(int *x) { + int mytype[getArraySize(x)]; + return 0; +} diff --git a/test/Analysis/traversal-algorithm.mm b/test/Analysis/traversal-algorithm.mm new file mode 100644 index 000000000000..8a3dc8b3a222 --- /dev/null +++ b/test/Analysis/traversal-algorithm.mm @@ -0,0 +1,213 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpTraversal -analyzer-max-loop 4 -std=c++11 %s | FileCheck -check-prefix=DFS %s + +int a(); +int b(); +int c(); + +int work(); + +void test(id input) { + if (a()) { + if (a()) + b(); + else + c(); + } else { + if (b()) + a(); + else + c(); + } + + if (a()) + work(); +} + +void testLoops(id input) { + while (a()) { + work(); + work(); + work(); + } + + for (int i = 0; i != b(); ++i) { + work(); + } + + for (id x in input) { + work(); + work(); + work(); + } + + int z[] = {1,2,3}; + for (int y : z) { + work(); + work(); + work(); + } +} + +// This ordering assumes that false cases happen before the true cases. + +// DFS:27 WhileStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:27 WhileStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:27 WhileStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:27 WhileStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:33 ForStmt +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:44 CXXForRangeStmt +// DFS-next:--END PATH-- +// DFS-next:37 ObjCForCollectionStmt +// DFS-next:10 IfStmt +// DFS-next:16 IfStmt +// DFS-next:22 IfStmt +// DFS-next:--END PATH-- +// DFS-next:--END PATH-- +// DFS-next:22 IfStmt +// DFS-next:--END PATH-- +// DFS-next:--END PATH-- +// DFS-next:11 IfStmt +// DFS-next:22 IfStmt +// DFS-next:--END PATH-- +// DFS-next:--END PATH-- +// DFS-next:22 IfStmt +// DFS-next:--END PATH-- +// DFS-next:--END PATH-- + diff --git a/test/Analysis/uninit-sometimes.cpp b/test/Analysis/uninit-sometimes.cpp new file mode 100644 index 000000000000..7825e8734616 --- /dev/null +++ b/test/Analysis/uninit-sometimes.cpp @@ -0,0 +1,387 @@ +// RUN: %clang_cc1 -std=gnu++11 -Wsometimes-uninitialized -verify %s +// RUN: %clang_cc1 -std=gnu++11 -Wsometimes-uninitialized -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +bool maybe(); + +int test_if_false(bool b) { + int x; // expected-note {{variable}} + if (b) // expected-warning {{whenever 'if' condition is false}} \ + // expected-note {{remove the 'if' if its condition is always true}} + x = 1; + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{8:3-10:5}:"" +// CHECK: fix-it:"{{.*}}":{7:8-7:8}:" = 0" + + +int test_if_true(bool b) { + int x; // expected-note {{variable}} + if (b) {} // expected-warning {{whenever 'if' condition is true}} \ + // expected-note {{remove the 'if' if its condition is always false}} + else x = 1; + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{20:3-22:8}:"" +// CHECK: fix-it:"{{.*}}":{19:8-19:8}:" = 0" + + +int test_while_false(bool b) { + int x; // expected-note {{variable}} + while (b) { // expected-warning {{whenever 'while' loop exits because its condition is false}} \ + // expected-note {{remove the condition if it is always true}} + if (maybe()) { + x = 1; + break; + } + }; + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{32:10-32:11}:"true" +// CHECK: fix-it:"{{.*}}":{31:8-31:8}:" = 0" + + +int test_while_true(bool b) { + int x; // expected-note {{variable}} + while (b) { // expected-warning {{whenever 'while' loop is entered}} \ + // expected-note {{remove the condition if it is always false}} +label: + return x; // expected-note {{uninitialized use}} + } + x = 0; + goto label; +} + +// CHECK: fix-it:"{{.*}}":{48:10-48:11}:"false" +// CHECK: fix-it:"{{.*}}":{47:8-47:8}:" = 0" + + +int test_do_while_false(bool b) { + int x; // expected-note {{variable}} + do { + if (maybe()) { + x = 1; + break; + } + } while (b); // expected-warning {{whenever 'do' loop exits because its condition is false}} \ + // expected-note {{remove the condition if it is always true}} + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{68:12-68:13}:"true" +// CHECK: fix-it:"{{.*}}":{62:8-62:8}:" = 0" + + +int test_do_while_true(bool b) { + int x; // expected-note {{variable}} +goto label2; + do { +label1: + return x; // expected-note {{uninitialized use}} +label2: ; + } while (b); // expected-warning {{whenever 'do' loop condition is true}} \ + // expected-note {{remove the condition if it is always false}} + x = 0; + goto label1; +} + +// CHECK: fix-it:"{{.*}}":{84:12-84:13}:"false" +// CHECK: fix-it:"{{.*}}":{78:8-78:8}:" = 0" + + +int test_for_false(int k) { + int x; // expected-note {{variable}} + for (int n = 0; + n < k; // expected-warning {{whenever 'for' loop exits because its condition is false}} \ + // expected-note {{remove the condition if it is always true}} + ++n) { + if (maybe()) { + x = n; + break; + } + } + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{97:8-97:13}:"" +// CHECK: fix-it:"{{.*}}":{95:8-95:8}:" = 0" + + +int test_for_true(int k) { + int x; // expected-note {{variable}} + int n = 0; + for (; + n < k; // expected-warning {{whenever 'for' loop is entered}} \ + // expected-note {{remove the condition if it is always false}} + ++n) { +label: + return x; // expected-note {{uninitialized use}} + } + x = 1; + goto label; +} + +// CHECK: fix-it:"{{.*}}":{116:8-116:13}:"false" +// CHECK: fix-it:"{{.*}}":{113:8-113:8}:" = 0" + + +int test_for_range_false(int k) { + int arr[3] = { 1, 2, 3 }; + int x; + for (int &a : arr) { // no-warning, condition was not explicitly specified + if (a == k) { + x = &a - arr; + break; + } + } + return x; +} + + + + + +int test_for_range_true(int k) { + int arr[3] = { 1, 2, 3 }; + int x; + for (int &a : arr) { // no-warning + goto label; + } + x = 0; +label: + return x; +} + + + + + +int test_conditional_false(int k) { + int x; // expected-note {{variable}} + (void)( + maybe() // expected-warning {{whenever '?:' condition is false}} \ + // expected-note {{remove the '?:' if its condition is always true}} + ? x = 1 : 0); + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{164:7-166:9}:"" +// CHECK: fix-it:"{{.*}}":{166:14-166:18}:"" +// CHECK: fix-it:"{{.*}}":{162:8-162:8}:" = 0" + +int test_conditional_true(int k) { + int x; // expected-note {{variable}} + (void)( + maybe() // expected-warning {{whenever '?:' condition is true}} \ + // expected-note {{remove the '?:' if its condition is always false}} + ? 0 : x = 1); + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{177:7-179:13}:"" +// CHECK: fix-it:"{{.*}}":{175:8-175:8}:" = 0" + + +int test_logical_and_false(int k) { + int x; // expected-note {{variable}} + maybe() // expected-warning {{whenever '&&' condition is false}} \ + // expected-note {{remove the '&&' if its condition is always true}} + && (x = 1); + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{189:3-191:9}:"" +// CHECK: fix-it:"{{.*}}":{188:8-188:8}:" = 0" + + +int test_logical_and_true(int k) { + int x; // expected-note {{variable}} + maybe() // expected-warning {{whenever '&&' condition is true}} \ + // expected-note {{remove the '&&' if its condition is always false}} + && ({ goto skip_init; 0; }); + x = 1; +skip_init: + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{201:3-203:34}:"false" +// CHECK: fix-it:"{{.*}}":{200:8-200:8}:" = 0" + + +int test_logical_or_false(int k) { + int x; // expected-note {{variable}} + maybe() // expected-warning {{whenever '||' condition is false}} \ + // expected-note {{remove the '||' if its condition is always true}} + || ({ goto skip_init; 0; }); + x = 1; +skip_init: + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{215:3-217:34}:"true" +// CHECK: fix-it:"{{.*}}":{214:8-214:8}:" = 0" + + +int test_logical_or_true(int k) { + int x; // expected-note {{variable}} + maybe() // expected-warning {{whenever '||' condition is true}} \ + // expected-note {{remove the '||' if its condition is always false}} + || (x = 1); + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{229:3-231:9}:"" +// CHECK: fix-it:"{{.*}}":{228:8-228:8}:" = 0" + + +int test_switch_case(int k) { + int x; // expected-note {{variable}} + switch (k) { + case 0: + x = 0; + break; + case 1: // expected-warning {{whenever switch case is taken}} + break; + } + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{240:8-240:8}:" = 0" + + + +int test_switch_default(int k) { + int x; // expected-note {{variable}} + switch (k) { + case 0: + x = 0; + break; + case 1: + x = 1; + break; + default: // expected-warning {{whenever switch default is taken}} + break; + } + return x; // expected-note {{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{256:8-256:8}:" = 0" + + + +int test_switch_suppress_1(int k) { + int x; + switch (k) { + case 0: + x = 0; + break; + case 1: + x = 1; + break; + } + return x; // no-warning +} + + + + + +int test_switch_suppress_2(int k) { + int x; + switch (k) { + case 0: + case 1: + switch (k) { + case 0: + return 0; + case 1: + return 1; + } + case 2: + case 3: + x = 1; + } + return x; // no-warning +} + + + + + +int test_multiple_notes(int k) { + int x; // expected-note {{variable}} + if (k > 0) { + if (k == 5) + x = 1; + else if (k == 2) // expected-warning {{whenever 'if' condition is false}} \ + // expected-note {{remove the 'if' if its condition is always true}} + x = 2; + } else { + if (k == -5) + x = 3; + else if (k == -2) // expected-warning {{whenever 'if' condition is false}} \ + // expected-note {{remove the 'if' if its condition is always true}} + x = 4; + } + return x; // expected-note 2{{uninitialized use}} +} + +// CHECK: fix-it:"{{.*}}":{324:10-326:7}:"" +// CHECK: fix-it:"{{.*}}":{318:10-320:7}:"" +// CHECK: fix-it:"{{.*}}":{314:8-314:8}:" = 0" + +int test_no_false_positive_1(int k) { + int x; + if (k) + x = 5; + while (!k) + maybe(); + return x; +} + + + + + +int test_no_false_positive_2() { + int x; + bool b = false; + if (maybe()) { + x = 5; + b = true; + } + return b ? x : 0; +} + + +// FIXME: In this case, the variable is used uninitialized whenever the +// function's entry block is reached. Produce a diagnostic saying that +// the variable is uninitialized the first time it is used. +void test_null_pred_succ() { + int x; + if (0) + foo: x = 0; + if (x) + goto foo; +} + + + + +void foo(); +int PR13360(bool b) { + int x; // expected-note {{variable}} + if (b) { // expected-warning {{variable 'x' is used uninitialized whenever 'if' condition is true}} expected-note {{remove}} + do { + foo(); + } while (0); + } else { + x = 1; + } + return x; // expected-note {{uninitialized use occurs here}} +} + +// CHECK: fix-it:"{{.*}}":{376:3-380:10}:"" +// CHECK: fix-it:"{{.*}}":{375:8-375:8}:" = 0" diff --git a/test/Analysis/unused-ivars.m b/test/Analysis/unused-ivars.m index 894184078039..f04132ba4570 100644 --- a/test/Analysis/unused-ivars.m +++ b/test/Analysis/unused-ivars.m @@ -108,3 +108,24 @@ int radar_7254495(RDar7254495 *a) { @implementation RDar8481311 @end + +@class NSString; +@interface Radar11059352_1 { +@private + NSString *_pathString; +} +@property (readonly, strong) NSString *pathString; +@end + +@interface Radar11059352 { +@private +Radar11059352_1 *_workspacePath; +} +@end + +@implementation Radar11059352 + +- (void)useWorkspace { + NSString *workspacePathString = _workspacePath.pathString; +} +@end
\ No newline at end of file |