197 lines
3.4 KiB
Objective-C
197 lines
3.4 KiB
Objective-C
// RUN: %clang_analyze_cc1 -analyzer-config eagerly-assume=false %s -analyzer-checker=osx.cocoa.RetainCount,deadcode.DeadStores,core -analyzer-output=plist -analyzer-config deadcode.DeadStores:ShowFixIts=true -o %t.plist
|
||
// RUN: %normalize_plist <%t.plist | diff -ub %S/Inputs/expected-plists/plist-output.m.plist -
|
||
|
||
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;
|
||
}
|
||
|
||
void test_assumptions(int a, int b)
|
||
{
|
||
if (a == 0) {
|
||
return;
|
||
}
|
||
if (b != 0) {
|
||
return;
|
||
}
|
||
int *p = 0;
|
||
*p = 0xDEADBEEF;
|
||
}
|
||
|
||
int *bar_cond_assign();
|
||
int test_cond_assign() {
|
||
int *p;
|
||
if (p = bar_cond_assign())
|
||
return 1;
|
||
return *p;
|
||
}
|
||
|
||
// The following previously crashed when generating extensive diagnostics.
|
||
// <rdar://problem/10797980>
|
||
@interface RDar10797980_help
|
||
@property (readonly) int x;
|
||
@end
|
||
|
||
@interface RDar10797980 {
|
||
RDar10797980_help *y;
|
||
}
|
||
- (void) test;
|
||
@end
|
||
|
||
@implementation RDar10797980
|
||
- (void) test {
|
||
if (y.x == 1) {
|
||
int *p = 0;
|
||
*p = 0xDEADBEEF; // expected-warning {{deference}}
|
||
}
|
||
}
|
||
|
||
// The original source for the above Radar contains another problem:
|
||
// if the end-of-path node is an implicit statement, it may not have a valid
|
||
// source location. <rdar://problem/12446776>
|
||
- (void)test2 {
|
||
if (bar_cond_assign()) {
|
||
id foo = [[RDar10797980 alloc] init]; // leak
|
||
}
|
||
(void)y; // first statement after the 'if' is an implicit 'self' DeclRefExpr
|
||
}
|
||
|
||
@end
|
||
|
||
// Test that loops are documented in the path.
|
||
void rdar12280665() {
|
||
for (unsigned i = 0; i < 2; ++i) {
|
||
if (i == 1) {
|
||
int *p = 0;
|
||
*p = 0xDEADBEEF; // expected-warning {{dereference}}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Test for a "loop executed 0 times" diagnostic.
|
||
int *radar12322528_bar();
|
||
|
||
void radar12322528_for(int x) {
|
||
int *p = 0;
|
||
for (unsigned i = 0; i < x; ++i) {
|
||
p = radar12322528_bar();
|
||
}
|
||
*p = 0xDEADBEEF;
|
||
}
|
||
|
||
void radar12322528_while(int x) {
|
||
int *p = 0;
|
||
unsigned i = 0;
|
||
for ( ; i < x ; ) {
|
||
++i;
|
||
p = radar12322528_bar();
|
||
}
|
||
*p = 0xDEADBEEF;
|
||
}
|
||
|
||
void radar12322528_foo_2() {
|
||
int *p = 0;
|
||
for (unsigned i = 0; i < 2; ++i) {
|
||
if (i == 1)
|
||
break;
|
||
}
|
||
*p = 0xDEADBEEF;
|
||
}
|
||
|
||
void test_loop_diagnostics() {
|
||
int *p = 0;
|
||
for (int i = 0; i < 2; ++i) { p = 0; }
|
||
*p = 1;
|
||
}
|
||
|
||
void test_loop_diagnostics_2() {
|
||
int *p = 0;
|
||
for (int i = 0; i < 2; ) {
|
||
++i;
|
||
p = 0;
|
||
}
|
||
*p = 1;
|
||
}
|
||
|
||
void test_loop_diagnostics_3() {
|
||
int *p = 0;
|
||
int i = 0;
|
||
while (i < 2) {
|
||
++i;
|
||
p = 0;
|
||
}
|
||
*p = 1;
|
||
}
|
||
|
||
void test_loop_fast_enumeration(id arr) {
|
||
int x;
|
||
for (id obj in arr) {
|
||
x = 1;
|
||
}
|
||
x += 1;
|
||
}
|
||
|
||
@interface RDar12114812 { char *p; }
|
||
@end
|
||
|
||
@implementation RDar12114812
|
||
- (void)test {
|
||
p = 0;
|
||
*p = 1;
|
||
}
|
||
@end
|
||
|
||
// Test diagnostics for initialization of structs.
|
||
void RDar13295437_f(void *i) __attribute__((__nonnull__));
|
||
|
||
struct RDar13295437_S { int *i; };
|
||
|
||
int RDar13295437() {
|
||
struct RDar13295437_S s = {0};
|
||
struct RDar13295437_S *sp = &s;
|
||
RDar13295437_f(sp->i);
|
||
}
|
||
|
||
@interface Foo
|
||
- (int *) returnsPointer;
|
||
@end
|
||
|
||
int testFoo(Foo *x) {
|
||
if (x)
|
||
return 1;
|
||
return *[x returnsPointer];
|
||
}
|
||
|