1*0a6a1f1dSLionel Sambuc// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -verify -fblocks %s 2*0a6a1f1dSLionel Sambuc 3*0a6a1f1dSLionel Sambuc@class NSString; 4*0a6a1f1dSLionel Sambuctypedef long NSInteger; 5*0a6a1f1dSLionel Sambuctypedef unsigned char BOOL; 6*0a6a1f1dSLionel Sambuc@interface NSObject {} 7*0a6a1f1dSLionel Sambuc+(id)alloc; 8*0a6a1f1dSLionel Sambuc-(id)init; 9*0a6a1f1dSLionel Sambuc-(id)autorelease; 10*0a6a1f1dSLionel Sambuc-(id)copy; 11*0a6a1f1dSLionel Sambuc-(id)retain; 12*0a6a1f1dSLionel Sambuc@end 13*0a6a1f1dSLionel Sambuc@interface NSNumber : NSObject 14*0a6a1f1dSLionel Sambuc+ (NSNumber *)numberWithInteger:(NSInteger)value __attribute__((availability(ios,introduced=2.0))); 15*0a6a1f1dSLionel Sambuc@end 16*0a6a1f1dSLionel Sambuc 17*0a6a1f1dSLionel SambucNSInteger *inoutIntegerValueGlobal; 18*0a6a1f1dSLionel SambucNSInteger *inoutIntegerValueGlobal2; 19*0a6a1f1dSLionel SambucNSString *traitNameGlobal; 20*0a6a1f1dSLionel Sambucstatic BOOL cond; 21*0a6a1f1dSLionel Sambuc 22*0a6a1f1dSLionel Sambucstatic inline void reallyPerformAction(void (^integerHandler)(NSInteger *inoutIntegerValue, NSString *traitName)) { 23*0a6a1f1dSLionel Sambuc integerHandler(inoutIntegerValueGlobal, traitNameGlobal); 24*0a6a1f1dSLionel Sambuc integerHandler(inoutIntegerValueGlobal2,traitNameGlobal); 25*0a6a1f1dSLionel Sambuc} 26*0a6a1f1dSLionel Sambuc 27*0a6a1f1dSLionel Sambucstatic inline BOOL performAction(NSNumber *(^action)(NSNumber *traitValue)) { 28*0a6a1f1dSLionel Sambuc __attribute__((__blocks__(byref))) BOOL didFindTrait = 0; 29*0a6a1f1dSLionel Sambuc reallyPerformAction(^(NSInteger *inoutIntegerValue,NSString *traitName) { 30*0a6a1f1dSLionel Sambuc 31*0a6a1f1dSLionel Sambuc if (cond) { 32*0a6a1f1dSLionel Sambuc 33*0a6a1f1dSLionel Sambuc NSNumber *traitValue = @(*inoutIntegerValue); 34*0a6a1f1dSLionel Sambuc 35*0a6a1f1dSLionel Sambuc NSNumber *newTraitValue = action(traitValue); 36*0a6a1f1dSLionel Sambuc 37*0a6a1f1dSLionel Sambuc if (traitValue != newTraitValue) { 38*0a6a1f1dSLionel Sambuc *inoutIntegerValue = newTraitValue ? *inoutIntegerValue : *inoutIntegerValue; 39*0a6a1f1dSLionel Sambuc } 40*0a6a1f1dSLionel Sambuc didFindTrait = 1; 41*0a6a1f1dSLionel Sambuc } 42*0a6a1f1dSLionel Sambuc 43*0a6a1f1dSLionel Sambuc }); 44*0a6a1f1dSLionel Sambuc return didFindTrait; 45*0a6a1f1dSLionel Sambuc} 46*0a6a1f1dSLionel Sambuc 47*0a6a1f1dSLionel Sambucvoid runTest() { 48*0a6a1f1dSLionel Sambuc __attribute__((__blocks__(byref))) NSNumber *builtinResult = ((NSNumber *)0); 49*0a6a1f1dSLionel Sambuc BOOL wasBuiltinTrait = performAction(^(NSNumber *traitValue) { 50*0a6a1f1dSLionel Sambuc builtinResult = [traitValue retain]; // expected-warning {{Potential leak of an object}} 51*0a6a1f1dSLionel Sambuc 52*0a6a1f1dSLionel Sambuc return traitValue; 53*0a6a1f1dSLionel Sambuc }); 54*0a6a1f1dSLionel Sambuc if (wasBuiltinTrait) { 55*0a6a1f1dSLionel Sambuc [builtinResult autorelease]; 56*0a6a1f1dSLionel Sambuc return; 57*0a6a1f1dSLionel Sambuc } else { 58*0a6a1f1dSLionel Sambuc return; 59*0a6a1f1dSLionel Sambuc } 60*0a6a1f1dSLionel Sambuc} 61