1// Temporarily disabling the test, it failes the "system is over-constrained"
2// assertion in *non* optimized builds.
3// REQUIRES: rdar44992170
4// RUN: %clang_analyze_cc1 -fblocks -analyze -analyzer-checker=core,nullability,apiModeling,debug.ExprInspection  -verify %s
5
6#include "Inputs/system-header-simulator-for-nullability.h"
7
8void clang_analyzer_warnIfReached();
9
10NSString* _Nonnull trust_nonnull_framework_annotation() {
11  NSString* out = [NSString generateString];
12  if (out) {}
13  return out; // no-warning
14}
15
16NSString* _Nonnull trust_instancemsg_annotation(NSString* _Nonnull param) {
17  NSString* out = [param stringByAppendingString:@"string"];
18  if (out) {}
19  return out; // no-warning
20}
21
22NSString* _Nonnull distrust_instancemsg_noannotation(NSString* param) {
23  if (param) {}
24  NSString* out = [param stringByAppendingString:@"string"];
25  if (out) {}
26  return out; // expected-warning{{}}
27}
28
29NSString* _Nonnull trust_analyzer_knowledge(NSString* param) {
30  if (!param)
31    return @"";
32  NSString* out = [param stringByAppendingString:@"string"];
33  if (out) {}
34  return out; // no-warning
35}
36
37NSString* _Nonnull trust_assume_nonnull_macro() {
38  NSString* out = [NSString generateImplicitlyNonnullString];
39  if (out) {}
40  return out; // no-warning
41}
42
43NSString* _Nonnull distrust_without_annotation() {
44  NSString* out = [NSString generatePossiblyNullString];
45  if (out) {}
46  return out; // expected-warning{{}}
47}
48
49NSString* _Nonnull nonnull_please_trust_me();
50
51NSString* _Nonnull distrust_local_nonnull_annotation() {
52  NSString* out = nonnull_please_trust_me();
53  if (out) {}
54  return out; // expected-warning{{}}
55}
56
57NSString* _Nonnull trust_c_function() {
58  NSString* out = getString();
59  if (out) {};
60  return out; // no-warning
61}
62
63NSString* _Nonnull distrust_unannoted_function() {
64  NSString* out = getPossiblyNullString();
65  if (out) {};
66  return out; // expected-warning{{}}
67}
68
69NSString * _Nonnull distrustProtocol(id<MyProtocol> o) {
70  NSString* out = [o getString];
71  if (out) {};
72  return out; // expected-warning{{}}
73}
74
75// If the return value is non-nil, the index is non-nil.
76NSString *_Nonnull retImpliesIndex(NSString *s,
77                                   NSDictionary *dic) {
78  id obj = dic[s];
79  if (s) {}
80  if (obj)
81    return s; // no-warning
82  return @"foo";
83}
84
85NSString *_Nonnull retImpliesIndexOtherMethod(NSString *s,
86                                   NSDictionary *dic) {
87  id obj = [dic objectForKey:s];
88  if (s) {}
89  if (obj)
90    return s; // no-warning
91  return @"foo";
92}
93
94NSString *_Nonnull retImpliesIndexOnRHS(NSString *s,
95                                        NSDictionary *dic) {
96  id obj = dic[s];
97  if (s) {}
98  if (nil != obj)
99    return s; // no-warning
100  return @"foo";
101}
102
103NSString *_Nonnull retImpliesIndexReverseCheck(NSString *s,
104                                               NSDictionary *dic) {
105  id obj = dic[s];
106  if (s) {}
107  if (!obj)
108    return @"foo";
109  return s; // no-warning
110}
111
112NSString *_Nonnull retImpliesIndexReverseCheckOnRHS(NSString *s,
113                                                    NSDictionary *dic) {
114  id obj = dic[s];
115  if (s) {}
116  if (nil == obj)
117    return @"foo";
118  return s; // no-warning
119}
120
121NSString *_Nonnull retImpliesIndexWrongBranch(NSString *s,
122                                              NSDictionary *dic) {
123  id obj = dic[s];
124  if (s) {}
125  if (!obj)
126    return s; // expected-warning{{}}
127  return @"foo";
128}
129
130NSString *_Nonnull retImpliesIndexWrongBranchOnRHS(NSString *s,
131                                                   NSDictionary *dic) {
132  id obj = dic[s];
133  if (s) {}
134  if (nil == obj)
135    return s; // expected-warning{{}}
136  return @"foo";
137}
138
139// The return value could still be nil for a non-nil index.
140NSDictionary *_Nonnull indexDoesNotImplyRet(NSString *s,
141                                            NSDictionary *dic) {
142  id obj = dic[s];
143  if (obj) {}
144  if (s)
145    return obj; // expected-warning{{}}
146  return [[NSDictionary alloc] init];
147}
148
149// The return value could still be nil for a non-nil index.
150NSDictionary *_Nonnull notIndexImpliesNotRet(NSString *s,
151                                             NSDictionary *dic) {
152  id obj = dic[s];
153  if (!s) {
154    if (obj != nil) {
155      clang_analyzer_warnIfReached(); // no-warning
156    }
157  }
158  return [[NSDictionary alloc] init];
159}
160
161NSString *_Nonnull checkAssumeOnMutableDictionary(NSMutableDictionary *d,
162                                                  NSString *k,
163                                                  NSString *val) {
164  d[k] = val;
165  if (k) {}
166  return k; // no-warning
167}
168
169NSString *_Nonnull checkAssumeOnMutableDictionaryOtherMethod(NSMutableDictionary *d,
170                                                             NSString *k,
171                                                             NSString *val) {
172  [d setObject:val forKey:k];
173  if (k) {}
174  return k; // no-warning
175}
176
177// Check that we don't crash when the added assumption is enough
178// to make the state unfeasible.
179@class DummyClass;
180@interface DictionarySubclass : NSDictionary {
181  DummyClass *g;
182  DictionarySubclass *d;
183}
184@end
185@implementation DictionarySubclass
186- (id) objectForKey:(id)e {
187  if (e) {}
188  return d;
189}
190- (void) coder {
191  for (id e in g) {
192    id f = [self objectForKey:e];
193    if (f)
194      (void)e;
195  }
196}
197@end
198