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 | |
7 | typedef __typeof(sizeof(int)) size_t; |
8 | void *memset(void *, int, size_t); |
9 | |
10 | #define nil 0 |
11 | typedef unsigned long NSUInteger; |
12 | typedef 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 | |
47 | void 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 | |
55 | void 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. |
65 | void testAlloca(size_t NSArrayClassSizeWeKnowSomehow) { |
66 | NSArray *arr = __builtin_alloca(NSArrayClassSizeWeKnowSomehow); |
67 | memset(arr, 0, NSArrayClassSizeWeKnowSomehow); |
68 | [arr init]; // no-crash |
69 | } |
70 | |