1 | // RUN: %clang_analyze_cc1 -Wno-objc-literal-conversion -analyzer-checker=core,unix.Malloc,osx.cocoa.NonNilReturnValue,debug.ExprInspection -analyzer-store=region -verify %s |
2 | |
3 | void clang_analyzer_eval(int); |
4 | |
5 | typedef signed char BOOL; |
6 | typedef long NSInteger; |
7 | typedef unsigned long NSUInteger; |
8 | |
9 | @protocol NSObject |
10 | @end |
11 | @interface NSObject <NSObject> {} |
12 | @end |
13 | @protocol NSCopying |
14 | @end |
15 | @protocol NSCoding |
16 | @end |
17 | |
18 | @interface NSString @end |
19 | @interface NSString (NSStringExtensionMethods) |
20 | + (id)stringWithUTF8String:(const char *)nullTerminatedCString; |
21 | @end |
22 | |
23 | @interface NSNumber |
24 | + (NSNumber *)numberWithChar:(char)value; |
25 | + (NSNumber *)numberWithUnsignedChar:(unsigned char)value; |
26 | + (NSNumber *)numberWithShort:(short)value; |
27 | + (NSNumber *)numberWithUnsignedShort:(unsigned short)value; |
28 | + (NSNumber *)numberWithInt:(int)value; |
29 | + (NSNumber *)numberWithUnsignedInt:(unsigned int)value; |
30 | + (NSNumber *)numberWithLong:(long)value; |
31 | + (NSNumber *)numberWithUnsignedLong:(unsigned long)value; |
32 | + (NSNumber *)numberWithLongLong:(long long)value; |
33 | + (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; |
34 | + (NSNumber *)numberWithFloat:(float)value; |
35 | + (NSNumber *)numberWithDouble:(double)value; |
36 | + (NSNumber *)numberWithBool:(BOOL)value; |
37 | + (NSNumber *)numberWithInteger:(NSInteger)value ; |
38 | + (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ; |
39 | @end |
40 | |
41 | @interface NSValue : NSObject <NSCopying, NSCoding> |
42 | - (void)getValue:(void *)value; |
43 | + (NSValue *)valueWithBytes:(const void *)value |
44 | objCType:(const char *)type; |
45 | @end |
46 | |
47 | typedef typeof(sizeof(int)) size_t; |
48 | extern void *malloc(size_t); |
49 | extern void free(void *); |
50 | extern char *strdup(const char *str); |
51 | |
52 | id constant_string() { |
53 | return @("boxed constant string."); |
54 | } |
55 | |
56 | id dynamic_string() { |
57 | return @(strdup("boxed dynamic string")); // expected-warning{{Potential memory leak}} |
58 | } |
59 | |
60 | typedef struct __attribute__((objc_boxable)) { |
61 | const char *str; |
62 | } BoxableStruct; |
63 | |
64 | id leak_within_boxed_struct() { |
65 | BoxableStruct bs; |
66 | bs.str = strdup("dynamic string"); // The duped string shall be owned by val. |
67 | NSValue *val = @(bs); // no-warning |
68 | return val; |
69 | } |
70 | |
71 | id leak_of_boxed_struct() { |
72 | BoxableStruct *bs = malloc(sizeof(BoxableStruct)); // The pointer stored in bs isn't owned by val. |
73 | NSValue *val = @(*bs); // expected-warning{{Potential leak of memory pointed to by 'bs'}} |
74 | return val; |
75 | } |
76 | |
77 | id const_char_pointer(int *x) { |
78 | if (x) |
79 | return @(3); |
80 | return @(*x); // expected-warning {{Dereference of null pointer (loaded from variable 'x')}} |
81 | } |
82 | |
83 | void checkNonNil() { |
84 | clang_analyzer_eval(!!@3); // expected-warning{{TRUE}} |
85 | clang_analyzer_eval(!!@(3+4)); // expected-warning{{TRUE}} |
86 | clang_analyzer_eval(!!@(57.0)); // expected-warning{{TRUE}} |
87 | |
88 | const char *str = "abc"; |
89 | clang_analyzer_eval(!!@(str)); // expected-warning{{TRUE}} |
90 | clang_analyzer_eval(!!@__objc_yes); // expected-warning{{TRUE}} |
91 | } |
92 | |
93 | |