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