CheckNSError.m revision c4d2c9074be6eb2091086eddd6c8f052f3b245c8
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,cocoa.NSError,macosx.CFError -analyzer-store=basic -analyzer-constraints=basic -verify %s
2// RUN: %clang_cc1 -analyze -analyzer-checker=core,cocoa.NSError,macosx.CFError -analyzer-store=region -analyzer-constraints=basic -verify %s
3// RUN: %clang_cc1 -analyze -analyzer-checker=core,cocoa.NSError,macosx.CFError -analyzer-store=basic -analyzer-constraints=range -verify %s
4// RUN: %clang_cc1 -analyze -analyzer-checker=core,cocoa.NSError,macosx.CFError -analyzer-store=region -analyzer-constraints=range -verify %s
5
6
7typedef signed char BOOL;
8typedef int NSInteger;
9typedef struct _NSZone NSZone;
10@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
11@protocol NSObject  - (BOOL)isEqual:(id)object; @end
12@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
13@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
14@interface NSObject <NSObject> {} @end
15@class NSDictionary;
16@interface NSError : NSObject <NSCopying, NSCoding> {}
17+ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict;
18@end
19extern NSString * const NSXMLParserErrorDomain ;
20
21@interface A
22- (void)myMethodWhichMayFail:(NSError **)error;
23- (BOOL)myMethodWhichMayFail2:(NSError **)error;
24@end
25
26@implementation A
27- (void)myMethodWhichMayFail:(NSError **)error {   // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred}}
28  *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference.}}
29}
30
31- (BOOL)myMethodWhichMayFail2:(NSError **)error {  // no-warning
32  if (error) *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // no-warning
33  return 0;
34}
35@end
36
37struct __CFError {};
38typedef struct __CFError* CFErrorRef;
39
40void foo(CFErrorRef* error) { // expected-warning {{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occurred}}
41  *error = 0;  // expected-warning {{Potential null dereference.}}
42}
43
44int f1(CFErrorRef* error) {
45  if (error) *error = 0; // no-warning
46  return 0;
47}
48
49int f2(CFErrorRef* error) {
50  if (0 != error) *error = 0; // no-warning
51  return 0;
52}
53
54int f3(CFErrorRef* error) {
55  if (error != 0) *error = 0; // no-warning
56  return 0;
57}
58
59
60