Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Analysis / inlining / path-notes.m
blob003100fc08107c5deac266e1b37bc239082fd7c4
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=text -analyzer-config suppress-null-return-paths=false -fblocks -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false -fblocks %s -o %t.plist
3 // RUN: %normalize_plist <%t.plist | diff -ub %S/Inputs/expected-plists/path-notes.m.plist -
5 typedef struct dispatch_queue_s *dispatch_queue_t;
6 typedef void (^dispatch_block_t)(void);
7 void dispatch_sync(dispatch_queue_t, dispatch_block_t);
9 typedef long dispatch_once_t;
10 // Note: The real dispatch_once has all parameters marked nonnull.
11 // We don't do that here so that we can trigger a null dereference inside
12 // the synthesized body.
13 void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
16 @interface Test
17 @property int *p;
18 @end
20 typedef unsigned long NSUInteger;
21 typedef signed char BOOL;
22 typedef struct _NSZone NSZone;
23 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
24 @protocol NSObject
25 @end
26 @protocol NSCopying
27 - (id)copyWithZone:(NSZone *)zone;
28 @end
29 @protocol NSMutableCopying
30 - (id)mutableCopyWithZone:(NSZone *)zone;
31 @end
32 @protocol NSCoding
33 - (void)encodeWithCoder:(NSCoder *)aCoder;
34 @end
35 @protocol NSFastEnumeration
36 @end
37 @protocol NSSecureCoding <NSCoding>
38 @required
39 + (BOOL)supportsSecureCoding;
40 @end
41 @interface NSObject <NSObject> {}
42 - (id)init;
43 + (id)alloc;
44 - (id)autorelease;
45 @end
46 @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
48 - (NSUInteger)count;
49 - (id)objectAtIndex:(NSUInteger)index;
51 @end
53 @interface NSArray (NSExtendedArray)
54 - (NSArray *)arrayByAddingObject:(id)anObject;
55 - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx __attribute__((availability(macosx,introduced=10.8)));
56 @end
58 @interface NSArray (NSArrayCreation)
59 + (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
60 @end
62 @interface NSMutableArray : NSArray
64 - (void)addObject:(id)anObject;
65 - (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
66 - (void)removeLastObject;
67 - (void)removeObjectAtIndex:(NSUInteger)index;
68 - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
70 @end
72 int *getZeroIfNil(Test *x) {
73   return x.p;
74   // expected-note@-1 {{'p' not called because the receiver is nil}}
75   // expected-note@-2 {{Returning null pointer}}
78 void testReturnZeroIfNil(void) {
79   *getZeroIfNil(0) = 1; // expected-warning{{Dereference of null pointer}}
80   // expected-note@-1 {{Calling 'getZeroIfNil'}}
81   // expected-note@-2 {{Passing nil object reference via 1st parameter 'x'}}
82   // expected-note@-3 {{Returning from 'getZeroIfNil'}}
83   // expected-note@-4 {{Dereference of null pointer}}
87 int testDispatchSyncInlining(void) {
88   extern dispatch_queue_t globalQueue;
90   __block int x;
92   // expected-note@+2 {{Calling 'dispatch_sync'}}
93   // expected-note@+1 {{Returning from 'dispatch_sync'}}
94   dispatch_sync(globalQueue, ^{
95     // expected-note@-1 {{Calling anonymous block}}
96     // expected-note@-2 {{Returning to caller}}
97     x = 0;
98     // expected-note@-1 {{The value 0 is assigned to 'x'}}
99   });
101   return 1 / x; // expected-warning{{Division by zero}}
102   // expected-note@-1 {{Division by zero}}
105 int testDispatchSyncInliningNoPruning(int coin) {
106   // This tests exactly the same case as above, except on a bug report where
107   // path pruning is disabled (an uninitialized variable capture).
108   // In this case 
109   extern dispatch_queue_t globalQueue;
111   __block int y;
113   // expected-note@+1 {{Calling 'dispatch_sync'}}
114   dispatch_sync(globalQueue, ^{
115     // expected-note@-1 {{Calling anonymous block}}
116     int x;
117     // expected-note@-1 {{'x' declared without an initial value}}
118     ^{ y = x; }(); // expected-warning{{Variable 'x' is uninitialized when captured by block}}
119     // expected-note@-1 {{'x' is uninitialized when captured by block}}
120   });
122   return y;
126 @interface PointerWrapper
127 - (int *)getPtr;
128 @end
130 id getNil(void) {
131   return 0;
134 void testNilReceiverHelper(int *x) {
135   *x = 1; // expected-warning {{Dereference of null pointer}}
136   // expected-note@-1 {{Dereference of null pointer (loaded from variable 'x')}}
139 void testNilReceiver(id *x, id *y, id *z) {
140   // FIXME: Should say "Assuming pointer value is null" instead.
141   // For some reason we're displaying different notes for
142   // tracked and untracked pointers.
143   if (*y) {} // expected-note    {{Assuming the condition is false}}
144              // expected-note@-1 {{Taking false branch}}
145   if (*x) { // expected-note {{Assuming pointer value is null}}
146     // expected-note@-1 {{Taking false branch}}
147     return;
148   }
149   // FIXME: Should say "Assuming pointer value is null" instead.
150   if (*z) {} // expected-note    {{Assuming the condition is false}}
151              // expected-note@-1 {{Taking false branch}}
152   testNilReceiverHelper([*x getPtr]);
153   // expected-note@-1 {{'getPtr' not called because the receiver is nil}}
154   // expected-note@-2 {{Passing null pointer value via 1st parameter 'x'}}
155   // expected-note@-3 {{Calling 'testNilReceiverHelper'}}
158 id testCreateArrayLiteral(id myNil) {
159   if (myNil) // expected-note {{Assuming 'myNil' is nil}}
160     ;        // expected-note@-1 {{Taking false branch}}
161   return @[ @"a", myNil, @"c" ]; // expected-warning {{Array element cannot be nil}}
162                                  //expected-note@-1 {{Array element cannot be nil}}
165 id testAutoreleaseTakesEffectInDispatch(void) {
166   static dispatch_once_t token = 0;
167   dispatch_once(&token, ^{});
169   id x = [[[[NSObject alloc] init] autorelease] autorelease];
170   // expected-note@-1 {{Method returns an instance of NSObject with a +1 retain count}}
171   // expected-note@-2 {{Object autoreleased}}
172   // expected-note@-3 {{Object autoreleased}}
174   dispatch_once(&token, ^{}); // don't crash, don't warn here
176   return x; // expected-warning{{Object autoreleased too many times}}
177   // expected-note@-1 {{Object was autoreleased 2 times but the object has a +0 retain count}}
180 void testNullDereferenceInDispatch(void) {
181   dispatch_once(0, ^{}); // no-warning, don't crash