-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Description
| Bugzilla Link | 2600 |
| Resolution | FIXED |
| Resolved on | Nov 07, 2018 00:22 |
| Version | unspecified |
| OS | All |
| Reporter | LLVM Bugzilla Contributor |
| CC | @tkremenek |
Extended Description
Here's an idea for another static analyzer check:
If a method accepts NSError** argument, based on ObjC conventions and recommendations from Apple that method should have non-void return value.
From "Creating and Returning NSError Objects" [1]
"In general, these methods should not indicate an error through the existence of an NSError object. Instead, they should return NO or nil from the method to indicate that an error occurred. Return the NSError object to describe the error."
For example:
- (void)myMethodWhichMayFail:(NSError *)error {
error = [NSError errorWithDomain:@"domain" code:1 userInfo:nil];
// expected-warning: {{Method accepting NSError argument should have non-void return value to indicate that an error occurred.}}
}
The correct way, for example:
- (BOOL)myMethodWhichMayFail:(NSError **)error {
*error = [NSError errorWithDomain:@"domain" code:1 userInfo:nil];
return FALSE; // no-warning
}
The example above is still dangerous, because caller of myMethodWhichMayFail: may not be interested in NSError and pass nil as 'error' argument, which would cause null dereference (which clang doesn't notice at this moment). So another static analysis check could make sure that code checks that 'error' argument is not null before dereferencing it. For example:
- (BOOL)myMethodWhichMayFail:(NSError **)error {
*error = [NSError errorWithDomain:@"domain" code:1 userInfo:nil];
// expected-warning: {{Potential null dereference. 'error' may be NULL.}}
return FALSE;
}
A simple if check would be enough to fix this:
- (BOOL)myMethodWhichMayFail:(NSError **)error {
if(error != nil)
*error = [NSError errorWithDomain:@"domain" code:1 userInfo:nil];
// no-warning
return FALSE;
}