BugReporter &BR) const;
private:
std::vector<std::string> SelectorsWithAutoreleasingPool = {
+ // Common to NSArray, NSSet, NSOrderedSet
"enumerateObjectsUsingBlock:",
- "enumerateKeysAndObjectsUsingBlock:",
- "enumerateKeysAndObjectsWithOptions:usingBlock:",
"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:",
+ "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 = {
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(),
typedef signed char BOOL;
+#define YES ((BOOL)1)
@protocol NSObject - (BOOL)isEqual:(id)object; @end
@interface NSObject <NSObject> {}
+(id)alloc;
@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> {}
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;
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);
});
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);
});
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);
});
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);
});
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;
}