1// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
2// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -DSUPPRESSED=1 %s
3// RUN: %clang_analyze_cc1 -analyzer-checker=core -fobjc-arc -verify -DSUPPRESSED=1 %s
4// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
5
6#define ARC __has_feature(objc_arc)
7
8#ifdef SUPPRESSED
9// expected-no-diagnostics
10#endif
11
12@interface PointerWrapper
13- (int *)getPtr;
14- (id)getObject;
15@end
16
17id getNil() {
18  return 0;
19}
20
21void testNilReceiverHelperA(int *x) {
22  *x = 1;
23#ifndef SUPPRESSED
24  // expected-warning@-2 {{Dereference of null pointer}}
25#endif
26}
27
28void testNilReceiverHelperB(int *x) {
29  *x = 1;
30#if !defined(SUPPRESSED)
31  // expected-warning@-2 {{Dereference of null pointer}}
32#endif
33}
34
35void testNilReceiver(int coin) {
36  id x = getNil();
37  if (coin)
38    testNilReceiverHelperA([x getPtr]);
39  else
40    testNilReceiverHelperB([[x getObject] getPtr]);
41}
42
43// FALSE NEGATIVES (over-suppression)
44
45__attribute__((objc_root_class))
46@interface SomeClass {
47  int ivar;
48}
49-(int *)methodReturningNull;
50
51@property(readonly) int *propertyReturningNull;
52
53@property(readonly) int *synthesizedProperty;
54
55@property(readonly) SomeClass *propertyReturningNil;
56
57@end
58
59@interface SubOfSomeClass : SomeClass
60@end
61
62@implementation SubOfSomeClass
63@end
64
65@implementation SomeClass
66-(int *)methodReturningNull {
67  return 0;
68}
69
70-(int *)propertyReturningNull {
71  return 0;
72}
73
74-(SomeClass *)propertyReturningNil {
75  return 0;
76}
77
78+(int *)classPropertyReturningNull {
79  return 0;
80}
81@end
82
83void testMethodReturningNull(SomeClass *sc) {
84  int *result = [sc methodReturningNull];
85  *result = 1;
86#ifndef SUPPRESSED
87  // expected-warning@-2 {{Dereference of null pointer}}
88#endif
89}
90
91void testPropertyReturningNull(SomeClass *sc) {
92  int *result = sc.propertyReturningNull;
93  *result = 1;
94#ifndef SUPPRESSED
95  // expected-warning@-2 {{Dereference of null pointer}}
96#endif
97}
98
99@implementation SubOfSomeClass (ForTestOfSuperProperty)
100-(void)testSuperPropertyReturningNull {
101  int *result = super.propertyReturningNull;
102  *result = 1;
103#ifndef SUPPRESSED
104  // expected-warning@-2 {{Dereference of null pointer}}
105#endif
106}
107@end
108
109void testClassPropertyReturningNull() {
110  int *result = SomeClass.classPropertyReturningNull;
111  *result = 1;
112#ifndef SUPPRESSED
113  // expected-warning@-2 {{Dereference of null pointer}}
114#endif
115}
116
117@implementation SomeClass (ForTestOfPropertyReturningNil)
118void testPropertyReturningNil(SomeClass *sc) {
119  SomeClass *result = sc.propertyReturningNil;
120  result->ivar = 1;
121#ifndef SUPPRESSED
122  // expected-warning@-2 {{Access to instance variable 'ivar' results in a dereference of a null pointer (loaded from variable 'result')}}
123#endif
124}
125@end
126
127void testSynthesizedPropertyReturningNull(SomeClass *sc) {
128  if (sc.synthesizedProperty)
129    return;
130
131  int *result = sc.synthesizedProperty;
132  *result = 1;
133#ifndef SUPPRESSED
134  // expected-warning@-2 {{Dereference of null pointer}}
135#endif
136}
137