[analyzer] ObjCAutoreleaseWrite: Support a few more APIs and fix warning text.

API list and improved warning text composed by Devin Coughlin.

llvm-svn: 331089
This commit is contained in:
Artem Dergachev 2018-04-27 22:00:51 +00:00
parent efc0f8cbdc
commit befce13328
2 changed files with 75 additions and 16 deletions

View File

@ -51,18 +51,43 @@ public:
BugReporter &BR) const;
private:
std::vector<std::string> SelectorsWithAutoreleasingPool = {
// Common to NSArray, NSSet, NSOrderedSet
"enumerateObjectsUsingBlock:",
"enumerateObjectsWithOptions:usingBlock:",
// Common to NSArray and NSOrderedSet
"enumerateObjectsAtIndexes:options:usingBlock:",
"indexOfObjectAtIndexes:options:passingTest:",
"indexesOfObjectsAtIndexes:options:passingTest:",
"indexOfObjectPassingTest:",
"indexOfObjectWithOptions:passingTest:",
"indexesOfObjectsPassingTest:",
"indexesOfObjectsWithOptions:passingTest:",
// NSDictionary
"enumerateKeysAndObjectsUsingBlock:",
"enumerateKeysAndObjectsWithOptions:usingBlock:",
"enumerateObjectsWithOptions:usingBlock:",
"enumerateObjectsAtIndexes:options:usingBlock:",
"keysOfEntriesPassingTest:",
"keysOfEntriesWithOptions:passingTest:",
// NSSet
"objectsPassingTest:",
"objectsWithOptions:passingTest:",
"enumerateIndexPathsWithOptions:usingBlock:",
// NSIndexSet
"enumerateIndexesWithOptions:usingBlock:",
"enumerateIndexesUsingBlock:",
"enumerateIndexesInRange:options:usingBlock:",
"enumerateRangesUsingBlock:",
"enumerateRangesWithOptions:usingBlock:",
"enumerateRangesInRange:options:usingBlock:"
"objectWithOptions:passingTest:",
"enumerateRangesInRange:options:usingBlock:",
"indexPassingTest:",
"indexesPassingTest:",
"indexWithOptions:passingTest:",
"indexesWithOptions:passingTest:",
"indexInRange:options:passingTest:",
"indexesInRange:options:passingTest:"
};
std::vector<std::string> FunctionsWithAutoreleasingPool = {
@ -95,9 +120,9 @@ static void emitDiagnostics(BoundNodes &Match, const Decl *D, BugReporter &BR,
assert(SW);
BR.EmitBasicReport(
ADC->getDecl(), Checker,
/*Name=*/"Writing into auto-releasing variable from a different queue",
/*Name=*/"Write to autoreleasing out parameter inside autorelease pool",
/*Category=*/"Memory",
(llvm::Twine("Writing into an auto-releasing out parameter inside ") +
(llvm::Twine("Write to autoreleasing out parameter inside ") +
"autorelease pool that may exit before " + Name + " returns; consider "
"writing first to a strong local variable declared outside of the block")
.str(),

View File

@ -4,6 +4,7 @@
typedef signed char BOOL;
#define YES ((BOOL)1)
@protocol NSObject - (BOOL)isEqual:(id)object; @end
@interface NSObject <NSObject> {}
+(id)alloc;
@ -14,6 +15,8 @@ typedef signed char BOOL;
@end
typedef int NSZone;
typedef int NSCoder;
typedef unsigned long NSUInteger;
@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
@interface NSError : NSObject <NSCopying, NSCoding> {}
@ -23,8 +26,27 @@ typedef int NSCoder;
typedef int dispatch_semaphore_t;
typedef void (^block_t)();
typedef enum {
NSEnumerationConcurrent = (1UL << 0),
NSEnumerationReverse = (1UL << 1)
} NSEnumerationOptions;
@interface NSArray
- (void) enumerateObjectsUsingBlock:(block_t)block;
- (void)enumerateObjectsUsingBlock:(block_t)block;
@end
@interface NSSet
- (void)objectsPassingTest:(block_t)block;
@end
@interface NSDictionary
- (void)enumerateKeysAndObjectsUsingBlock:(block_t)block;
@end
@interface NSIndexSet
- (void)indexesPassingTest:(block_t)block;
- (NSUInteger)indexWithOptions:(NSEnumerationOptions)opts
passingTest:(BOOL (^)(NSUInteger idx, BOOL *stop))predicate;
@end
typedef int group_t;
@ -69,7 +91,7 @@ BOOL writeToErrorWithIterator(NSError ** error, NSArray *a) {
dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
dispatch_async(queue, ^{
if (error) {
*error = [NSError errorWithDomain:1]; // expected-warning{{Writing into an auto-releasing out parameter inside autorelease pool that may exit before method returns}}
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before method returns; consider writing first to a strong local variable declared outside of the block}}
}
dispatch_semaphore_signal(sem);
});
@ -82,7 +104,7 @@ BOOL writeToErrorWithIterator(NSError ** error, NSArray *a) {
dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
dispatch_group_async(queue, 0, ^{
if (error) {
*error = [NSError errorWithDomain:1]; // expected-warning{{Writing into an auto-releasing out}}
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before method returns; consider writing first to a strong local variable declared outside of the block}}
}
dispatch_semaphore_signal(sem);
});
@ -123,14 +145,14 @@ BOOL writeToErrorWithIterator(NSError ** error, NSArray *a) {
dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
dispatch_async(queue, ^{
if (error) {
*error = [NSError errorWithDomain:1]; // expected-warning{{Writing into an auto-releasing out}}
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before method returns; consider writing first to a strong local variable declared outside of the block}}
}
dispatch_semaphore_signal(sem);
});
dispatch_async(queue, ^{
if (error) {
*error = [NSError errorWithDomain:1]; // expected-warning{{Writing into an auto-releasing out}}
*error = [NSError errorWithDomain:1]; // expected-warning{{Writing into an auto-releasing out}}
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before method returns; consider writing first to a strong local variable declared outside of the block}}
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before method returns; consider writing first to a strong local variable declared outside of the block}}
}
dispatch_semaphore_signal(sem);
});
@ -150,7 +172,7 @@ BOOL writeToErrorInBlockFromCFunc(NSError *__autoreleasing* error) {
dispatch_semaphore_t sem = dispatch_semaphore_create(0l);
dispatch_async(queue, ^{
if (error) {
*error = [NSError errorWithDomain:1]; // expected-warning{{Writing into an auto-releasing out}}
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
}
dispatch_semaphore_signal(sem);
});
@ -164,9 +186,21 @@ BOOL writeToErrorNoWarning(NSError *__autoreleasing* error) {
return 0;
}
BOOL writeToErrorWithIterator(NSError *__autoreleasing* error, NSArray *a) {
[a enumerateObjectsUsingBlock:^{
*error = [NSError errorWithDomain:1]; // expected-warning{{Writing into an auto-releasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
BOOL writeToErrorWithIterator(NSError *__autoreleasing* error, NSArray *a, NSSet *s, NSDictionary *d, NSIndexSet *i) { [a enumerateObjectsUsingBlock:^{
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
}];
[d enumerateKeysAndObjectsUsingBlock:^{
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
}];
[s objectsPassingTest:^{
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
}];
[i indexesPassingTest:^{
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
}];
[i indexWithOptions: NSEnumerationReverse passingTest:^(NSUInteger idx, BOOL *stop) {
*error = [NSError errorWithDomain:1]; // expected-warning{{Write to autoreleasing out parameter inside autorelease pool that may exit before function returns; consider writing first to a strong local variable declared outside of the block}}
return YES;
}];
return 0;
}