1// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.ObjCGenerics -verify %s
2
3#if !__has_feature(objc_generics)
4#  error Compiler does not support Objective-C generics?
5#endif
6
7typedef __typeof(sizeof(int)) size_t;
8void *memset(void *, int, size_t);
9
10#define nil 0
11typedef unsigned long NSUInteger;
12typedef int BOOL;
13
14@protocol NSCopying
15@end
16
17__attribute__((objc_root_class))
18@interface NSObject
19- (void) myFunction:(int*)p myParam:(int) n;
20@end
21
22@interface MyType : NSObject <NSCopying>
23- (void) myFunction:(int*)p myParam:(int) n;
24@end
25
26@interface NSArray<ObjectType> : NSObject
27- (void) init;
28- (BOOL)contains:(ObjectType)obj;
29- (ObjectType)getObjAtIndex:(NSUInteger)idx;
30- (ObjectType)objectAtIndexedSubscript:(NSUInteger)idx;
31@property(readonly) ObjectType firstObject;
32@end
33
34@implementation NSObject
35- (void) myFunction:(int*)p myParam:(int) n {
36  (void)*p;// no warning
37}
38@end
39
40@implementation MyType
41- (void) myFunction:(int*)p myParam:(int) n {
42  int i = 5/n;  // expected-warning {{}}
43  (void)i;
44}
45@end
46
47void testReturnType(NSArray<MyType *> *arr) {
48  NSArray *erased = arr;
49  NSObject *element = [erased firstObject];
50  // TODO: myFunction currently dispatches to NSObject. Make it dispatch to
51  // MyType instead!
52  [element myFunction:0 myParam:0 ];
53}
54
55void testArgument(NSArray<MyType *> *arr, id element) {
56  NSArray *erased = arr;
57  [erased contains: element];
58  // TODO: myFunction currently is not dispatched to MyType. Make it dispatch to
59  // MyType!
60  [element myFunction:0 myParam:0 ];
61}
62
63// Do not try this at home! The analyzer shouldn't crash though when it
64// tries to figure out the dynamic type behind the alloca's return value.
65void testAlloca(size_t NSArrayClassSizeWeKnowSomehow) {
66  NSArray *arr = __builtin_alloca(NSArrayClassSizeWeKnowSomehow);
67  memset(arr, 0, NSArrayClassSizeWeKnowSomehow);
68  [arr init]; // no-crash
69}
70