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 5extern 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 21int 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 31int 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 40int 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 52extern 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