diff options
Diffstat (limited to 'test/Analysis')
27 files changed, 1036 insertions, 73 deletions
diff --git a/test/Analysis/MissingDealloc.m b/test/Analysis/MissingDealloc.m index 3942391..21460a1 100644 --- a/test/Analysis/MissingDealloc.m +++ b/test/Analysis/MissingDealloc.m @@ -1,4 +1,4 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -warn-objc-missing-dealloc '-DIBOutlet=__attribute__((iboutlet))' %s --verify +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -warn-objc-missing-dealloc '-DIBOutlet=__attribute__((iboutlet))' %s -verify typedef signed char BOOL; @protocol NSObject - (BOOL)isEqual:(id)object; @@ -39,7 +39,7 @@ typedef struct objc_selector *SEL; @end -@implementation TestSELs // no-warning +@implementation TestSELs - (id)init { if( (self = [super init]) ) { a = @selector(a); diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c index fc9e27b..bee337a 100644 --- a/test/Analysis/casts.c +++ b/test/Analysis/casts.c @@ -1,4 +1,4 @@ -// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region --verify %s +// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify %s // Test if the 'storage' region gets properly initialized after it is cast to // 'struct sockaddr *'. diff --git a/test/Analysis/casts.m b/test/Analysis/casts.m index 4e201bf..69a4260 100644 --- a/test/Analysis/casts.m +++ b/test/Analysis/casts.m @@ -1,5 +1,5 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic --verify %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region --verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify %s // Test function pointer casts. Currently we track function addresses using // loc::FunctionVal. Because casts can be arbitrary, do we need to model diff --git a/test/Analysis/cfref_PR2519.c b/test/Analysis/cfref_PR2519.c index ee1da1f..d9367d4 100644 --- a/test/Analysis/cfref_PR2519.c +++ b/test/Analysis/cfref_PR2519.c @@ -1,7 +1,7 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=basic -analyzer-constraints=basic -verify %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=basic -analyzer-constraints=range -verify %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region -analyzer-constraints=basic -verify %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region -analyzer-constraints=range -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s typedef unsigned char Boolean; typedef signed long CFIndex; diff --git a/test/Analysis/concrete-address.c b/test/Analysis/concrete-address.c index 31802d0..96080be 100644 --- a/test/Analysis/concrete-address.c +++ b/test/Analysis/concrete-address.c @@ -1,5 +1,5 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic --verify %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region --verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify %s void foo() { int *p = (int*) 0x10000; // Should not crash here. diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index 811ac81..e29eefd 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -1,8 +1,8 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -warn-dead-stores -verify %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -warn-dead-stores -verify %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=range -warn-dead-stores -verify %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -warn-dead-stores -verify %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -warn-dead-stores -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -warn-dead-stores -fblocks -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -warn-dead-stores -fblocks -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=range -warn-dead-stores -fblocks -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -warn-dead-stores -fblocks -verify %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -warn-dead-stores -fblocks -verify %s void f1() { int k, y; @@ -34,7 +34,7 @@ void f4(int k) { k = 2; // expected-warning {{never read}} } - + void f5() { int x = 4; // no-warning @@ -55,6 +55,24 @@ int f7(int *p) { return 1; } +int f7b(int *p) { + // This is allowed for defensive programming. + p = (0); // no-warning + return 1; +} + +int f7c(int *p) { + // This is allowed for defensive programming. + p = (void*) 0; // no-warning + return 1; +} + +int f7d(int *p) { + // This is allowed for defensive programming. + p = (void*) (0); // no-warning + return 1; +} + int f8(int *p) { extern int *baz(); if ((p = baz())) // expected-warning{{Although the value}} @@ -336,3 +354,19 @@ void f22() { break; } } + +void f23_aux(const char* s); +void f23(int argc, char **argv) { + int shouldLog = (argc > 1); // no-warning + ^{ + if (shouldLog) f23_aux("I did too use it!\n"); + else f23_aux("I shouldn't log. Wait.. d'oh!\n"); + }(); +} + +void f23_pos(int argc, char **argv) { + int shouldLog = (argc > 1); // expected-warning{{Value stored to 'shouldLog' during its initialization is never read}} + ^{ + f23_aux("I did too use it!\n"); + }(); +} diff --git a/test/Analysis/fields.c b/test/Analysis/fields.c index d6bc845..7ea6111 100644 --- a/test/Analysis/fields.c +++ b/test/Analysis/fields.c @@ -1,5 +1,5 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref %s --analyzer-store=basic -verify -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref %s --analyzer-store=region -verify +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref %s -analyzer-store=basic -verify +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref %s -analyzer-store=region -verify unsigned foo(); typedef struct bf { unsigned x:2; } bf; diff --git a/test/Analysis/misc-ps-64.m b/test/Analysis/misc-ps-64.m index 506dc8b..f520784 100644 --- a/test/Analysis/misc-ps-64.m +++ b/test/Analysis/misc-ps-64.m @@ -1,7 +1,7 @@ -// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=basic -analyzer-constraints=basic --verify -fblocks %s -// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s -// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s -// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s +// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify -fblocks %s +// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify -fblocks %s +// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify -fblocks %s +// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s // <rdar://problem/6440393> - A bunch of misc. failures involving evaluating // these expressions and building CFGs. These tests are here to prevent diff --git a/test/Analysis/misc-ps-basic-store.m b/test/Analysis/misc-ps-basic-store.m index 2b99134..2a98234 100644 --- a/test/Analysis/misc-ps-basic-store.m +++ b/test/Analysis/misc-ps-basic-store.m @@ -1,4 +1,4 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=basic --verify -fblocks %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -verify -fblocks %s //--------------------------------------------------------------------------- // Test case 'checkaccess_union' differs for region store and basic store. diff --git a/test/Analysis/misc-ps-eager-assume.m b/test/Analysis/misc-ps-eager-assume.m index 66eb125..e702cb9 100644 --- a/test/Analysis/misc-ps-eager-assume.m +++ b/test/Analysis/misc-ps-eager-assume.m @@ -1,4 +1,4 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s -analyzer-eagerly-assume +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s -analyzer-eagerly-assume // Delta-reduced header stuff (needed for test cases). typedef signed char BOOL; diff --git a/test/Analysis/misc-ps-ranges.m b/test/Analysis/misc-ps-ranges.m index 49cc593..058c903 100644 --- a/test/Analysis/misc-ps-ranges.m +++ b/test/Analysis/misc-ps-ranges.m @@ -1,5 +1,5 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify -fblocks %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s // <rdar://problem/6776949> // main's 'argc' argument is always > 0 diff --git a/test/Analysis/misc-ps-region-store-i386.m b/test/Analysis/misc-ps-region-store-i386.m index a833a65..7b0d61b 100644 --- a/test/Analysis/misc-ps-region-store-i386.m +++ b/test/Analysis/misc-ps-region-store-i386.m @@ -1,4 +1,4 @@ -// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region --verify -fblocks %s +// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks %s // Here is a case where a pointer is treated as integer, invalidated as an // integer, and then used again as a pointer. This test just makes sure diff --git a/test/Analysis/misc-ps-region-store-x86_64.m b/test/Analysis/misc-ps-region-store-x86_64.m index 7e614fd..8c865ab 100644 --- a/test/Analysis/misc-ps-region-store-x86_64.m +++ b/test/Analysis/misc-ps-region-store-x86_64.m @@ -1,4 +1,4 @@ -// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region --verify -fblocks %s +// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks %s // Here is a case where a pointer is treated as integer, invalidated as an // integer, and then used again as a pointer. This test just makes sure diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 7ebc4a9..e5113ba 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -1,5 +1,5 @@ -// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region --verify -fblocks %s -// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region --verify -fblocks %s +// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks %s +// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks %s typedef struct objc_selector *SEL; typedef signed char BOOL; @@ -470,3 +470,74 @@ int pr3135() { return 0; } +//===----------------------------------------------------------------------===// +// <rdar://problem/7403269> - Test that we handle compound initializers with +// partially unspecified array values. Previously this caused a crash. +//===----------------------------------------------------------------------===// + +typedef struct RDar7403269 { + unsigned x[10]; + unsigned y; +} RDar7403269; + +void rdar7403269() { + RDar7403269 z = { .y = 0 }; + if (z.x[4] == 0) + return; + int *p = 0; + *p = 0xDEADBEEF; // no-warning +} + +typedef struct RDar7403269_b { + struct zorg { int w; int k; } x[10]; + unsigned y; +} RDar7403269_b; + +void rdar7403269_b() { + RDar7403269_b z = { .y = 0 }; + if (z.x[5].w == 0) + return; + int *p = 0; + *p = 0xDEADBEEF; // no-warning +} + +void rdar7403269_b_pos() { + RDar7403269_b z = { .y = 0 }; + if (z.x[5].w == 1) + return; + int *p = 0; + *p = 0xDEADBEEF; // expected-warning{{Dereference of null pointer}} +} + + +//===----------------------------------------------------------------------===// +// Test that incrementing a non-null pointer results in a non-null pointer. +// (<rdar://problem/7191542>) +//===----------------------------------------------------------------------===// + +void test_increment_nonnull_rdar_7191542(const char *path) { + const char *alf = 0; + + for (;;) { + // When using basic-store, we get a null dereference here because we lose information + // about path after the pointer increment. + char c = *path++; // no-warning + if (c == 'a') { + alf = path; + } + + if (alf) + return; + } +} + +//===----------------------------------------------------------------------===// +// Test that the store (implicitly) tracks values for doubles/floats that are +// uninitialized (<rdar://problem/6811085>) +//===----------------------------------------------------------------------===// + +double rdar_6811085(void) { + double u; + return u + 10; // expected-warning{{The left operand of '+' is a garbage value}} +} + diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index d2eef0d..42168b9 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-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=basic -fobjc-gc -analyzer-constraints=basic --verify -fblocks %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -fobjc-gc -analyzer-constraints=basic -verify -fblocks %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify -fblocks %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify -fblocks %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify -fblocks %s typedef struct objc_ivar *Ivar; typedef struct objc_selector *SEL; @@ -750,3 +750,46 @@ void test_undefined_array_subscript() { int *p = &a[i]; // expected-warning{{Array subscript is undefined}} } @end + +//===----------------------------------------------------------------------===// +// Test using an uninitialized value as a branch condition. +//===----------------------------------------------------------------------===// + +int test_uninit_branch(void) { + int x; + if (x) // expected-warning{{Branch condition evaluates to a garbage value}} + return 1; + return 0; +} + +int test_uninit_branch_b(void) { + int x; + return x ? 1 : 0; // expected-warning{{Branch condition evaluates to a garbage value}} +} + +int test_uninit_branch_c(void) { + int x; + if ((short)x) // expected-warning{{Branch condition evaluates to a garbage value}} + return 1; + return 0; +} + +//===----------------------------------------------------------------------===// +// Test passing an undefined value in a message or function call. +//===----------------------------------------------------------------------===// + +void test_bad_call_aux(int x); +void test_bad_call(void) { + int y; + test_bad_call_aux(y); // expected-warning{{Pass-by-value argument in function call is undefined}} +} + +@interface TestBadArg {} +- (void) testBadArg:(int) x; +@end + +void test_bad_msg(TestBadArg *p) { + int y; + [p testBadArg:y]; // expected-warning{{Pass-by-value argument in message expression is undefined}} +} + diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m index 536c4a1..75cdf6e 100644 --- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m +++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m @@ -1,5 +1,7 @@ -// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s -verify -// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-constraints=basic -analyzer-store=region %s -verify +// RUN: clang-cc -triple i386-apple-darwin8 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s 2>&1 | FileCheck -check-prefix=darwin8 %s +// RUN: clang-cc -triple i386-apple-darwin8 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-constraints=basic -analyzer-store=region %s 2>&1 | FileCheck -check-prefix=darwin8 %s +// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-constraints=basic -analyzer-store=basic %s 2>&1 | FileCheck -check-prefix=darwin9 %s +// RUN: clang-cc -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-constraints=basic -analyzer-store=region %s 2>&1 | FileCheck -check-prefix=darwin9 %s @interface MyClass {} - (void *)voidPtrM; @@ -28,20 +30,20 @@ void createFoo() { void createFoo2() { MyClass *obj = 0; - long double ld = [obj longDoubleM]; // expected-warning{{The receiver in the message expression is 'nil' and results in the returned value}} + long double ld = [obj longDoubleM]; // expected-warning{{The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage}} } void createFoo3() { MyClass *obj; obj = 0; - long long ll = [obj longlongM]; // expected-warning{{The receiver in the message expression is 'nil' and results in the returned value}} + long long ll = [obj longlongM]; // expected-warning{{The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage}} } void createFoo4() { MyClass *obj = 0; - double d = [obj doubleM]; // expected-warning{{The receiver in the message expression is 'nil' and results in the returned value}} + double d = [obj doubleM]; // expected-warning{{The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage}} } void createFoo5() { @@ -59,10 +61,22 @@ void handleNilPruneLoop(MyClass *obj) { long long j = [obj longlongM]; // no-warning } - long long j = [obj longlongM]; // expected-warning{{The receiver in the message expression is 'nil' and results in the returned value}} + long long j = [obj longlongM]; // expected-warning{{The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage}} } int handleVoidInComma() { MyClass *obj = 0; return [obj voidM], 0; } + +int marker(void) { // control reaches end of non-void function +} + +// CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage +// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage +// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage +// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage +// CHECK-darwin8: control reaches end of non-void function +// CHECK-darwin8: 5 diagnostics generated +// CHECK-darwin9: control reaches end of non-void function +// CHECK-darwin9: 1 diagnostic generated diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c index f5c6a10..c604653 100644 --- a/test/Analysis/null-deref-ps.c +++ b/test/Analysis/null-deref-ps.c @@ -26,7 +26,7 @@ int f2(struct foo_struct* p) { if (p) p->x = 1; - return p->x++; // expected-warning{{Dereference of null pointer.}} + return p->x++; // expected-warning{{Dereference of null pointer}} } int f3(char* x) { @@ -36,7 +36,7 @@ int f3(char* x) { if (x) return x[i - 1]; - return x[i+1]; // expected-warning{{Dereference of null pointer.}} + return x[i+1]; // expected-warning{{Dereference of null pointer}} } int f3_b(char* x) { @@ -46,7 +46,7 @@ int f3_b(char* x) { if (x) return x[i - 1]; - return x[i+1]++; // expected-warning{{Dereference of null pointer.}} + return x[i+1]++; // expected-warning{{Dereference of null pointer}} } int f4(int *p) { @@ -57,7 +57,7 @@ int f4(int *p) { return 1; int *q = (int*) x; - return *q; // expected-warning{{Dereference of null pointer.}} + return *q; // expected-warning{{Dereference of null pointer loaded from variable 'q'}} } int f4_b() { diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m index 8bd616a..971d476 100644 --- a/test/Analysis/plist-output.m +++ b/test/Analysis/plist-output.m @@ -1,9 +1,42 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref --analyzer-store=region -analyzer-constraints=range -fblocks --analyzer-output=plist -o - %s | FileCheck %s +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-output=plist -o - %s | FileCheck %s void test_null_init(void) { int *p = 0; *p = 0xDEADBEEF; } + +void test_null_assign(void) { + int *p; + p = 0; + *p = 0xDEADBEEF; +} + +void test_null_assign_transitive(void) { + int *p; + p = 0; + int *q = p; + *q = 0xDEADBEEF; +} + +void test_null_cond(int *p) { + if (!p) { + *p = 0xDEADBEEF; + } +} + +void test_null_cond_transitive(int *q) { + if (!q) { + int *p = q; + *p = 0xDEADBEEF; + } +} + +void test_null_field(void) { + struct s { int *p; } x; + x.p = 0; + *(x.p) = 0xDEADBEEF; +} + // 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"> @@ -102,6 +135,702 @@ void test_null_init(void) { // CHECK: </array> // CHECK: </array> // 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>5</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>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>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>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>3</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// 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> +// 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: <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>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>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>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>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// 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>11</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>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>15</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>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: </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>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>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>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>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>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>4</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>extended_message</key> +// CHECK: <string>Dereference of null pointer loaded from variable 'q'</string> +// CHECK: <key>message</key> +// CHECK: <string>Dereference of null pointer loaded from variable 'q'</string> +// CHECK: </dict> +// CHECK: </array> +// CHECK: <key>description</key><string>Dereference of null pointer loaded from variable 'q'</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>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>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>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: </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>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>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>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: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// 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>23</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>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>23</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>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>23</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// 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>23</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>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>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>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: </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>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>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>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>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>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: <key>end</key> +// CHECK: <array> +// CHECK: <dict> +// 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>30</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>event</string> +// CHECK: <key>location</key> +// CHECK: <dict> +// CHECK: <key>line</key><integer>30</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>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>30</integer> +// CHECK: <key>col</key><integer>6</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// 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>30</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>control</string> +// CHECK: <key>edges</key> +// CHECK: <array> +// CHECK: <dict> +// CHECK: <key>start</key> +// CHECK: <array> +// CHECK: <dict> +// 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>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>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>35</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>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>35</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>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>37</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>37</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>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>37</integer> +// CHECK: <key>col</key><integer>8</integer> +// CHECK: <key>file</key><integer>0</integer> +// CHECK: </dict> +// CHECK: </array> +// CHECK: </array> +// CHECK: <key>extended_message</key> // CHECK: <string>Dereference of null pointer</string> // CHECK: <key>message</key> // CHECK: <string>Dereference of null pointer</string> @@ -109,10 +838,10 @@ void test_null_init(void) { // CHECK: </array> // CHECK: <key>description</key><string>Dereference of null pointer</string> // CHECK: <key>category</key><string>Logic error</string> -// CHECK: <key>type</key><string>Null pointer dereference</string> +// CHECK: <key>type</key><string>Dereference of null pointer</string> // CHECK: <key>location</key> // CHECK: <dict> -// CHECK: <key>line</key><integer>5</integer> +// CHECK: <key>line</key><integer>37</integer> // CHECK: <key>col</key><integer>3</integer> // CHECK: <key>file</key><integer>0</integer> // CHECK: </dict> diff --git a/test/Analysis/rdar-6442306-1.m b/test/Analysis/rdar-6442306-1.m index 7b0a1a6..1d8bbd3 100644 --- a/test/Analysis/rdar-6442306-1.m +++ b/test/Analysis/rdar-6442306-1.m @@ -1,5 +1,5 @@ -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref %s --analyzer-store=basic -verify -// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref %s --analyzer-store=region -verify +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref %s -analyzer-store=basic -verify +// RUN: clang-cc -analyze -analyzer-experimental-internal-checks -checker-cfref %s -analyzer-store=region -verify typedef int bar_return_t; typedef struct { diff --git a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m index 7230f21..9d6fe5b 100644 --- a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m +++ b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m @@ -15,12 +15,12 @@ typedef struct Foo { int x; } Bar; void createFoo() { MyClass *obj = 0; - Bar f = [obj foo]; // expected-warning{{The receiver in the message expression is 'nil' and results in the returned value (of type 'Bar') to be garbage or otherwise undefined.}} + Bar f = [obj foo]; // expected-warning{{The receiver of message 'foo' is nil and returns a value of type 'Bar' that will be garbage}} } void createFoo2() { MyClass *obj = 0; [obj foo]; // no-warning - Bar f = [obj foo]; // expected-warning{{The receiver in the message expression is 'nil' and results in the returned value (of type 'Bar') to be garbage or otherwise undefined.}} + Bar f = [obj foo]; // expected-warning{{The receiver of message 'foo' is nil and returns a value of type 'Bar' that will be garbage}} } diff --git a/test/Analysis/region-only-test.c b/test/Analysis/region-only-test.c deleted file mode 100644 index 8908adb..0000000 --- a/test/Analysis/region-only-test.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s - -// Region store must be enabled for tests in this file. - -// Exercise creating ElementRegion with symbolic super region. -void foo(int* p) { - int *x; - int a; - if (p[0] == 1) - x = &a; - if (p[0] == 1) - (void)*x; // no-warning -} diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m index 3eeebc4..ab52938 100644 --- a/test/Analysis/retain-release-gc-only.m +++ b/test/Analysis/retain-release-gc-only.m @@ -1,5 +1,5 @@ -// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc-only %s -// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -fobjc-gc-only -verify %s +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify -fobjc-gc-only -fblocks %s +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -fobjc-gc-only -fblocks -verify %s //===----------------------------------------------------------------------===// // Header stuff. @@ -93,6 +93,7 @@ typedef struct _NSZone NSZone; + (id)alloc; - (void)dealloc; - (void)release; +- (id)copy; @end @interface NSObject (NSCoderMethods) - (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; @@ -332,6 +333,17 @@ void rdar_6250216(void) { [pool release]; // expected-warning{{Use -drain instead of -release when using NSAutoreleasePool and garbage collection}} } + +//===----------------------------------------------------------------------===// +// <rdar://problem/7407273> Don't crash when analyzing messages sent to blocks +//===----------------------------------------------------------------------===// + +@class RDar7407273; +typedef void (^RDar7407273Block)(RDar7407273 *operation); +void rdar7407273(RDar7407273Block b) { + [b copy]; +} + //===----------------------------------------------------------------------===// // Tests of ownership attributes. //===----------------------------------------------------------------------===// diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index dfea2e7..bc9f0b7 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -1,5 +1,5 @@ -// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=basic -verify %s -// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=region -verify %s +// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=basic -fblocks -verify %s +// RUN: clang-cc -triple x86_64-apple-darwin10 -analyze -checker-cfref -analyzer-store=region -fblocks -verify %s #if __has_feature(attribute_ns_returns_retained) #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) @@ -1162,6 +1162,19 @@ void rdar7306898(void) { } //===----------------------------------------------------------------------===// +// <rdar://problem/7252064> sending 'release', 'retain', etc. to a Class +// directly is not likely what the user intended +//===----------------------------------------------------------------------===// + +@interface RDar7252064 : NSObject @end +void rdar7252064(void) { + [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}} + [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}} + [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}} + [NSAutoreleasePool drain]; // expected-warning{{method '+drain' not found}} expected-warning{{The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly}} +} + +//===----------------------------------------------------------------------===// // Tests of ownership attributes. //===----------------------------------------------------------------------===// @@ -1259,3 +1272,34 @@ void test_panic_pos_2(int x) { panic(); } +//===----------------------------------------------------------------------===// +// Test uses of blocks (closures) +//===----------------------------------------------------------------------===// + +void test_blocks_1_pos(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} + ^{}(); +} + +void test_blocks_1_indirect_release(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + ^{ [number release]; }(); +} + +void test_blocks_1_indirect_retain(void) { + // Eventually this should be reported as a leak. + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + ^{ [number retain]; }(); +} + +void test_blocks_1_indirect_release_via_call(void) { + NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning + ^(NSObject *o){ [o release]; }(number); +} + +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 + ^(NSObject *o){ [o retain]; }(number); +} + diff --git a/test/Analysis/stack-addr-ps.c b/test/Analysis/stack-addr-ps.c index f26e2f0..5d1ce25 100644 --- a/test/Analysis/stack-addr-ps.c +++ b/test/Analysis/stack-addr-ps.c @@ -1,5 +1,5 @@ -// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -verify %s -// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -verify %s +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -fblocks -verify %s +// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -fblocks -verify %s int* f1() { int x = 0; @@ -55,3 +55,16 @@ int struct_test(struct baz byVal, int flag) { return byVal.y[0]; // no-warning } } + +typedef int (^ComparatorBlock)(int a, int b); +ComparatorBlock test_return_block(void) { + ComparatorBlock b = ^int(int a, int b){ return a > b; }; + return b; // expected-warning{{Address of stack-allocated block declared on line 61 returned to caller}} +} + +ComparatorBlock test_return_block_neg_aux(void); +ComparatorBlock test_return_block_neg(void) { + ComparatorBlock b = test_return_block_neg_aux(); + return b; // no-warning +} + diff --git a/test/Analysis/uninit-msg-expr.m b/test/Analysis/uninit-msg-expr.m index c2b7366..46e441f 100644 --- a/test/Analysis/uninit-msg-expr.m +++ b/test/Analysis/uninit-msg-expr.m @@ -42,7 +42,7 @@ extern NSString * const NSUndoManagerCheckpointNotification; unsigned f1() { NSString *aString; - return [aString length]; // expected-warning {{Receiver in message expression is an uninitialized value}} + return [aString length]; // expected-warning {{Receiver in message expression is a garbage value}} } unsigned f2() { diff --git a/test/Analysis/uninit-ps-rdar6145427.m b/test/Analysis/uninit-ps-rdar6145427.m index d9e7318..7be32b4 100644 --- a/test/Analysis/uninit-ps-rdar6145427.m +++ b/test/Analysis/uninit-ps-rdar6145427.m @@ -30,7 +30,7 @@ extern NSString * const NSUndoManagerCheckpointNotification; int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - id someUnintializedPointer = [someUnintializedPointer objectAtIndex:0]; // expected-warning{{Receiver in message expression is an uninitialized value.}} + id someUnintializedPointer = [someUnintializedPointer objectAtIndex:0]; // expected-warning{{Receiver in message expression is a garbage value}} NSLog(@"%@", someUnintializedPointer); [pool drain]; return 0; diff --git a/test/Analysis/unused-ivars.m b/test/Analysis/unused-ivars.m index 754799b..bbbf6ae 100644 --- a/test/Analysis/unused-ivars.m +++ b/test/Analysis/unused-ivars.m @@ -65,3 +65,19 @@ } @end +//===----------------------------------------------------------------------===// +// <rdar://problem/7254495> - ivars referenced by lexically nested functions +// should not be flagged as unused +//===----------------------------------------------------------------------===// + +@interface RDar7254495 { +@private + int x; // no-warning +} +@end + +@implementation RDar7254495 +int radar_7254495(RDar7254495 *a) { + return a->x; +} +@end |