1 // RUN: %clang_analyze_cc1 -fblocks -fobjc-arc -verify %s -Wno-objc-root-class \
2 // RUN: -analyzer-checker=core \
3 // RUN: -analyzer-checker=alpha.core.StackAddressAsyncEscape \
4 // RUN: -analyzer-checker=nullability \
5 // RUN: -analyzer-checker=osx
7 #include "Inputs/system-header-simulator-for-nullability.h"
8 #include "os_object_base.h"
10 struct OSIterator : public OSObject {
11 static const OSMetaClass * const metaClass;
14 @interface TestObject : NSObject
15 - (int *_Nonnull)returnsNonnull;
16 - (int *_Nullable)returnsNullable;
17 - (int *)returnsUnspecified;
18 - (void)takesNonnull:(int *_Nonnull)p;
19 - (void)takesNullable:(int *_Nullable)p;
20 - (void)takesUnspecified:(int *)p;
21 @property(readonly, strong) NSString *stuff;
24 TestObject * getUnspecifiedTestObject();
25 TestObject *_Nonnull getNonnullTestObject();
26 TestObject *_Nullable getNullableTestObject();
30 typedef struct Dummy { int val; } Dummy;
32 void takesNullable(Dummy *_Nullable);
33 void takesNonnull(Dummy *_Nonnull);
34 void takesUnspecified(Dummy *);
36 Dummy *_Nullable returnsNullable();
37 Dummy *_Nonnull returnsNonnull();
38 Dummy *returnsUnspecified();
39 int *_Nullable returnsNullableInt();
41 template <typename T> T *eraseNullab(T *p) { return p; }
43 void takesAttrNonnull(Dummy *p) __attribute((nonnull(1)));
45 void testBasicRules() {
46 // FIXME: None of these should be tied to a modeling checker.
47 Dummy *p = returnsNullable();
48 int *ptr = returnsNullableInt();
49 // Make every dereference a different path to avoid sinks after errors.
50 switch (getRandom()) {
52 Dummy &r = *p; // expected-warning {{Nullable pointer is dereferenced [nullability.NullableDereferenced]}}
55 int b = p->val; // expected-warning {{Nullable pointer is dereferenced [nullability.NullableDereferenced]}}
58 int stuff = *ptr; // expected-warning {{Nullable pointer is dereferenced [nullability.NullableDereferenced]}}
61 takesNonnull(p); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter [nullability.NullablePassedToNonnull]}}
70 takesAttrNonnull(p); // expected-warning {{Nullable pointer is passed to a callee that requires a non-null [nullability.NullableDereferenced]}}
72 default: { Dummy d = *p; } break; // expected-warning {{Nullable pointer is dereferenced [nullability.NullableDereferenced]}}
85 // FIXME: This shouldn't be tied to a modeling checker.
86 takesNonnull(q); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter [nullability.NullPassedToNonnull]}}
89 Dummy *_Nonnull nonnull = &a;
90 // FIXME: This shouldn't be tied to a modeling checker.
91 nonnull = q; // expected-warning {{Null assigned to a pointer which is expected to have non-null value [nullability.NullPassedToNonnull]}}
97 typedef int NSInteger;
98 typedef struct _NSZone NSZone;
99 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
101 @interface NSError : NSObject <NSCopying, NSCoding> {}
102 + (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict;
106 typedef struct __CFError* CFErrorRef;
108 void foo(CFErrorRef* error) { // expected-warning{{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occurred [osx.coreFoundation.CFError]}}
109 // FIXME: This shouldn't be tied to a modeling checker.
110 *error = 0; // expected-warning {{Potential null dereference. According to coding standards documented in CoreFoundation/CFError.h the parameter may be null [osx.coreFoundation.CFError]}}
114 - (void)myMethodWhichMayFail:(NSError **)error;
118 - (void)myMethodWhichMayFail:(NSError **)error { // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred [osx.cocoa.NSError]}}
119 *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference. According to coding standards in 'Creating and Returning NSError Objects' the parameter may be null [osx.cocoa.NSError]}}
123 bool write_into_out_param_on_success(OS_RETURNS_RETAINED OSObject **obj);
125 void use_out_param_leak() {
127 // FIXME: This shouldn't be tied to a modeling checker.
128 write_into_out_param_on_success(&obj); // expected-warning{{Potential leak of an object stored into 'obj' [osx.cocoa.RetainCount]}}
131 typedef struct dispatch_queue_s *dispatch_queue_t;
132 typedef void (^dispatch_block_t)(void);
133 void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
134 typedef long dispatch_once_t;
135 void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
136 typedef long dispatch_time_t;
137 void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);
138 void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);
140 extern dispatch_queue_t queue;
141 extern dispatch_once_t *predicate;
142 extern dispatch_time_t when;
144 dispatch_block_t get_leaking_block() {
150 // expected-warning@-3 {{Address of stack memory associated with local variable 'leaked_x' \
151 is captured by a returned block [core.StackAddressEscape]}}
154 void test_returned_from_func_block_async() {
155 dispatch_async(queue, get_leaking_block());
156 // expected-warning@-1 {{Address of stack memory associated with local variable 'leaked_x' \
157 is captured by an asynchronously-executed block [alpha.core.StackAddressAsyncEscape]}}