misc-ps.m revision eaedfeab9eab0d003859aab138784f2c59531408
1// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=basic --verify -fblocks %s &&
2// RUN: clang-cc -analyze -checker-cfref --analyzer-store=basic -analyzer-constraints=range --verify -fblocks %s
3
4// NOWORK: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=basic --verify -fblocks %s &&
5// NOWORK: clang-cc -analyze -checker-cfref --analyzer-store=region -analyzer-constraints=range --verify -fblocks %s
6
7typedef struct objc_selector *SEL;
8typedef signed char BOOL;
9typedef int NSInteger;
10typedef unsigned int NSUInteger;
11typedef struct _NSZone NSZone;
12@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
13@protocol NSObject  - (BOOL)isEqual:(id)object; @end
14@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
15@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
16@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
17@interface NSObject <NSObject> {} - (id)init; @end
18extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
19@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
20- (NSUInteger)length;
21+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
22@end extern NSString * const NSBundleDidLoadNotification;
23@interface NSAssertionHandler : NSObject {}
24+ (NSAssertionHandler *)currentHandler;
25- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
26@end
27extern NSString * const NSConnectionReplyMode;
28typedef float CGFloat;
29typedef struct _NSPoint {
30    CGFloat x;
31    CGFloat y;
32} NSPoint;
33typedef struct _NSSize {
34    CGFloat width;
35    CGFloat height;
36} NSSize;
37typedef struct _NSRect {
38    NSPoint origin;
39    NSSize size;
40} NSRect;
41
42// Reduced test case from crash in <rdar://problem/6253157>
43@interface A @end
44@implementation A
45- (void)foo:(void (^)(NSObject *x))block {
46  if (!((block != ((void *)0)))) {}
47}
48@end
49
50// Reduced test case from crash in PR 2796;
51//  http://llvm.org/bugs/show_bug.cgi?id=2796
52
53unsigned foo(unsigned x) { return __alignof__((x)) + sizeof(x); }
54
55// Improvement to path-sensitivity involving compound assignments.
56//  Addresses false positive in <rdar://problem/6268365>
57//
58
59unsigned r6268365Aux();
60
61void r6268365() {
62  unsigned x = 0;
63  x &= r6268365Aux();
64  unsigned j = 0;
65    
66  if (x == 0) ++j;
67  if (x == 0) x = x / j; // no-warning
68}
69
70void divzeroassume(unsigned x, unsigned j) {  
71  x /= j;  
72  if (j == 0) x /= 0;     // no-warning
73  if (j == 0) x /= j;     // no-warning
74  if (j == 0) x = x / 0;  // no-warning
75}
76
77void divzeroassumeB(unsigned x, unsigned j) {  
78  x = x / j;  
79  if (j == 0) x /= 0;     // no-warning
80  if (j == 0) x /= j;     // no-warning
81  if (j == 0) x = x / 0;  // no-warning
82}
83
84// InitListExpr processing
85
86typedef float __m128 __attribute__((__vector_size__(16), __may_alias__));
87__m128 return128() {
88  // This compound literal has a Vector type.  We currently just
89  // return UnknownVal.
90  return __extension__(__m128) { 0.0f, 0.0f, 0.0f, 0.0f };
91}
92
93typedef long long __v2di __attribute__ ((__vector_size__ (16)));
94typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
95__m128i vec128i(long long __q1, long long __q0) {
96  // This compound literal returns true for both isVectorType() and 
97  // isIntegerType().
98  return __extension__ (__m128i)(__v2di){ __q0, __q1 };
99}
100
101// Zero-sized VLAs.
102void check_zero_sized_VLA(int x) {
103  if (x)
104    return;
105
106  int vla[x]; // expected-warning{{Variable-length array 'vla' has zero elements (undefined behavior)}}
107}
108
109void check_uninit_sized_VLA() {
110  int x;
111  int vla[x]; // expected-warning{{Variable-length array 'vla' garbage value for array size}}
112}
113
114// sizeof(void)
115// - Tests a regression reported in PR 3211: http://llvm.org/bugs/show_bug.cgi?id=3211
116void handle_sizeof_void(unsigned flag) {
117  int* p = 0;
118
119  if (flag) {
120    if (sizeof(void) == 1)
121      return;
122    // Infeasible.
123    *p = 1; // no-warning
124  }
125  
126  void* q;
127  
128  if (!flag) {
129    if (sizeof(*q) == 1)
130      return;
131    // Infeasibe.
132    *p = 1; // no-warning
133  }
134    
135  // Infeasible.
136  *p = 1; // no-warning
137}
138
139// PR 3422
140void pr3422_helper(char *p);
141void pr3422() {
142  char buf[100];
143  char *q = &buf[10];
144  pr3422_helper(&q[1]);
145}
146
147// PR 3543 (handle empty statement expressions)
148int pr_3543(void) {
149  ({});
150}
151
152// <rdar://problem/6611677>
153// This test case test the use of a vector type within an array subscript
154// expression.
155typedef long long __a64vector __attribute__((__vector_size__(8)));
156typedef long long __a128vector __attribute__((__vector_size__(16)));
157static inline __a64vector __attribute__((__always_inline__, __nodebug__))  
158my_test_mm_movepi64_pi64(__a128vector a) {
159  return (__a64vector)a[0];
160}
161
162// Test basic tracking of ivars associated with 'self'.
163@interface SelfIvarTest : NSObject {
164  int flag;
165}
166- (void)test_self_tracking;
167@end
168
169@implementation SelfIvarTest
170- (void)test_self_tracking {
171  char *p = 0;
172  char c;
173
174  if (flag)
175    p = "hello";
176
177  if (flag)
178    c = *p; // no-warning
179}
180@end
181
182// PR 3770
183char pr3770(int x) {
184  int y = x & 0x2;
185  char *p = 0;
186  if (y == 1)
187    p = "hello";
188
189  if (y == 1)
190    return p[0]; // no-warning
191    
192  return 'a';
193}
194
195// PR 3772
196// - We just want to test that this doesn't crash the analyzer.
197typedef struct st ST;
198struct st { char *name; };
199extern ST *Cur_Pu;
200
201void pr3772(void)
202{
203  static ST *last_Cur_Pu;
204  if (last_Cur_Pu == Cur_Pu) {
205    return;
206  } 
207}
208
209// PR 3780 - This tests that StmtIterator isn't broken for VLAs in DeclGroups.
210void pr3780(int sz) { typedef double MAT[sz][sz]; }
211
212// <rdar://problem/6695527> - Test that we don't symbolicate doubles before
213// we are ready to do something with them.
214int rdar6695527(double x) {
215  if (!x) { return 0; }
216  return 1;
217}
218
219// <rdar://problem/6708148> - Test that we properly invalidate structs
220//  passed-by-reference to a function.
221void pr6708148_invalidate(NSRect *x);
222void pr6708148_use(NSRect x);
223void pr6708148_test(void) {
224  NSRect x;
225  pr6708148_invalidate(&x);
226  pr6708148_use(x); // no-warning
227}
228
229// Handle both kinds of noreturn attributes for pruning paths.
230void rdar_6777003_noret() __attribute__((noreturn));
231void rdar_6777003_analyzer_noret() __attribute__((analyzer_noreturn));
232
233void rdar_6777003(int x) {
234  int *p = 0;
235  
236  if (x == 1) {
237    rdar_6777003_noret();
238    *p = 1; // no-warning;    
239  }
240  
241  if (x == 2) {
242    rdar_6777003_analyzer_noret();
243    *p = 1; // no-warning;
244  }
245  
246  *p = 1; // expected-warning{{Dereference of null pointer}}  
247}
248
249// For pointer arithmetic, --/++ should be treated as preserving non-nullness,
250// regardless of how well the underlying StoreManager reasons about pointer
251// arithmetic.
252// <rdar://problem/6777209>
253void rdar_6777209(char *p) {
254  if (p == 0)
255    return;
256  
257  ++p;
258  
259  // This branch should always be infeasible.
260  if (p == 0)
261    *p = 'c'; // no-warning
262}
263
264// PR 4033.  A symbolic 'void *' pointer can be used as the address for a
265// computed goto.
266typedef void *Opcode;
267Opcode pr_4033_getOpcode();
268void pr_4033(void) {
269next_opcode:
270  {
271    Opcode op = pr_4033_getOpcode();
272    if (op) goto *op;
273  }
274}
275
276// Test invalidating pointers-to-pointers with slightly different types.  This
277// example came from a recent false positive due to a regression where the
278// branch condition was falsely reported as being uninitialized.
279void invalidate_by_ref(char **x);
280int test_invalidate_by_ref() {
281  unsigned short y;
282  invalidate_by_ref((char**) &y);
283  if (y) // no-warning
284    return 1;
285  return 0;  
286}
287
288