1 | // RUN: %clang_analyze_cc1 -x objective-c -analyzer-checker=core,nullability -analyzer-output=text -Wno-objc-root-class -fblocks -verify %s |
2 | |
3 | #include "../Inputs/system-header-simulator-for-nullability.h" |
4 | |
5 | extern int coin(); |
6 | |
7 | @interface I : NSObject |
8 | - (int)initVar:(int *)var param:(int)param; |
9 | @end |
10 | |
11 | @implementation I |
12 | - (int)initVar:(int *)var param:(int)param { |
13 | if (param) { // expected-note{{Taking false branch}} |
14 | *var = 1; |
15 | return 0; |
16 | } |
17 | return 1; // expected-note{{Returning without writing to '*var'}} |
18 | } |
19 | @end |
20 | |
21 | int foo(I *i) { |
22 | int x; //expected-note{{'x' declared without an initial value}} |
23 | int out = [i initVar:&x param:0]; //expected-note{{Calling 'initVar:param:'}} |
24 | //expected-note@-1{{Returning from 'initVar:param:'}} |
25 | if (out) // expected-note{{Taking true branch}} |
26 | return x; //expected-warning{{Undefined or garbage value returned to caller}} |
27 | //expected-note@-1{{Undefined or garbage value returned to caller}} |
28 | return 0; |
29 | } |
30 | |
31 | int initializer1(int *p, int x) { |
32 | if (x) { // expected-note{{Taking false branch}} |
33 | *p = 1; |
34 | return 0; |
35 | } else { |
36 | return 1; // expected-note {{Returning without writing to '*p'}} |
37 | } |
38 | } |
39 | |
40 | int initFromBlock() { |
41 | __block int z; |
42 | ^{ // expected-note {{Calling anonymous block}} |
43 | int p; // expected-note{{'p' declared without an initial value}} |
44 | initializer1(&p, 0); // expected-note{{Calling 'initializer1'}} |
45 | // expected-note@-1{{Returning from 'initializer1'}} |
46 | z = p; // expected-warning{{Assigned value is garbage or undefined}} |
47 | // expected-note@-1{{Assigned value is garbage or undefined}} |
48 | }(); |
49 | return z; |
50 | } |
51 | |
52 | extern void expectNonNull(NSString * _Nonnull a); |
53 | |
54 | @interface A : NSObject |
55 | - (void) initAMaybe; |
56 | @end |
57 | |
58 | @implementation A { |
59 | NSString * a; |
60 | } |
61 | |
62 | - (void) initAMaybe { |
63 | if (coin()) // expected-note{{Assuming the condition is false}} |
64 | // expected-note@-1{{Taking false branch}} |
65 | a = @"string"; |
66 | } // expected-note{{Returning without writing to 'self->a'}} |
67 | |
68 | - (void) passNullToNonnull { |
69 | a = nil; // expected-note{{nil object reference stored to 'a'}} |
70 | [self initAMaybe]; // expected-note{{Calling 'initAMaybe'}} |
71 | // expected-note@-1{{Returning from 'initAMaybe'}} |
72 | expectNonNull(a); // expected-warning{{nil passed to a callee that requires a non-null 1st parameter}} |
73 | // expected-note@-1{{nil passed to a callee that requires a non-null 1st parameter}} |
74 | } |
75 | |
76 | - (void) initAMaybeWithExplicitSelf { |
77 | if (coin()) // expected-note{{Assuming the condition is false}} |
78 | // expected-note@-1{{Taking false branch}} |
79 | self->a = @"string"; |
80 | } // expected-note{{Returning without writing to 'self->a'}} |
81 | |
82 | - (void) passNullToNonnullWithExplicitSelf { |
83 | self->a = nil; // expected-note{{nil object reference stored to 'a'}} |
84 | [self initAMaybeWithExplicitSelf]; // expected-note{{Calling 'initAMaybeWithExplicitSelf'}} |
85 | // expected-note@-1{{Returning from 'initAMaybeWithExplicitSelf'}} |
86 | expectNonNull(a); // expected-warning{{nil passed to a callee that requires a non-null 1st parameter}} |
87 | // expected-note@-1{{nil passed to a callee that requires a non-null 1st parameter}} |
88 | } |
89 | |
90 | - (void) initPassedAMaybe:(A *) param { |
91 | if (coin()) // expected-note{{Assuming the condition is false}} |
92 | // expected-note@-1{{Taking false branch}} |
93 | param->a = @"string"; |
94 | } // expected-note{{Returning without writing to 'param->a'}} |
95 | |
96 | - (void) useInitPassedAMaybe:(A *) paramA { |
97 | paramA->a = nil; // expected-note{{nil object reference stored to 'a'}} |
98 | [self initPassedAMaybe:paramA]; // expected-note{{Calling 'initPassedAMaybe:'}} |
99 | // expected-note@-1{{Returning from 'initPassedAMaybe:'}} |
100 | expectNonNull(paramA->a); // expected-warning{{nil passed to a callee that requires a non-null 1st parameter}} |
101 | // expected-note@-1{{nil passed to a callee that requires a non-null 1st parameter}} |
102 | |
103 | } |
104 | |
105 | @end |
106 | |