brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.2 KiB · 1e17cb7 Raw
254 lines · plain
1// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core -fblocks -verify -Wno-strict-prototypes %s2// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core -fblocks -verify -x objective-c++ %s3 4//===----------------------------------------------------------------------===//5// The following code is reduced using delta-debugging from Mac OS X headers:6//===----------------------------------------------------------------------===//7 8typedef __builtin_va_list va_list;9typedef unsigned int uint32_t;10typedef struct dispatch_queue_s *dispatch_queue_t;11typedef struct dispatch_queue_attr_s *dispatch_queue_attr_t;12typedef void (^dispatch_block_t)(void);13void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);14__attribute__((visibility("default"))) __attribute__((__malloc__)) __attribute__((__warn_unused_result__)) __attribute__((__nothrow__)) dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);15typedef long dispatch_once_t;16void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);17#if __cplusplus >= 201703L18__attribute__((__nothrow__))19#endif20dispatch_queue_t21dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);22 23 24typedef signed char BOOL;25typedef unsigned long NSUInteger;26typedef struct _NSZone NSZone;27@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;28@protocol NSObject29- (BOOL)isEqual:(id)object;30- (oneway void)release;31@end32@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end33@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end34@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end35@interface NSObject <NSObject> {}36+ (id)alloc;37- (id)init;38- (id)copy;39@end40extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);41@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>42- (NSUInteger)length;43- (const char *)UTF8String;44- (id)initWithFormat:(NSString *)format arguments:(va_list)argList __attribute__((format(__NSString__, 1, 0)));45@end46@class NSString, NSData;47typedef struct cssm_sample {} CSSM_SAMPLEGROUP, *CSSM_SAMPLEGROUP_PTR;48typedef struct __aslclient *aslclient;49typedef struct __aslmsg *aslmsg;50aslclient asl_open(const char *ident, const char *facility, uint32_t opts);51int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __attribute__((__format__ (__printf__, 4, 5)));52 53struct Block_layout {54  int flags;55};56 57//===----------------------------------------------------------------------===//58// Begin actual test cases.59//===----------------------------------------------------------------------===//60 61// test1 - This test case exposed logic that caused the analyzer to crash because of a memory bug62//  in BlockDataRegion.  It represents real code that contains two block literals.  Eventually63//  via IPA 'logQueue' and 'client' should be updated after the call to 'dispatch_once'.64void test1(NSString *format, ...) {65  static dispatch_queue_t logQueue;66  static aslclient client;67  static dispatch_once_t pred;68  do {69    if (__builtin_expect(*(&pred), ~0l) != ~0l)70      dispatch_once(&pred, ^{71        logQueue = dispatch_queue_create("com.mycompany.myproduct.asl", 0);72        client = asl_open(((char*)0), "com.mycompany.myproduct", 0);73      });74  } while (0);75 76  va_list args;77  __builtin_va_start(args, format);78 79  NSString *str = [[NSString alloc] initWithFormat:format arguments:args];80  dispatch_async(logQueue, ^{ asl_log(client, ((aslmsg)0), 4, "%s", [str UTF8String]); });81  [str release];82 83  __builtin_va_end(args);84}85 86// test2 - Test that captured variables that are uninitialized are flagged87// as such.88void test2(void) {89  static int y = 0;90  int x;91  ^{ y = x + 1; }();  // expected-warning{{Variable 'x' is uninitialized when captured by block}}92}93 94void test2_b(void) {95  static int y = 0;96  __block int x;97  ^{ y = x + 1; }(); // expected-warning {{left operand of '+' is a garbage value}}98}99 100void test2_c(void) {101  typedef void (^myblock)(void);102  myblock f = ^(void) { f(); }; // expected-warning{{Variable 'f' is uninitialized when captured by block}}103}104 105 106void testMessaging(void) {107  [[^(void){} copy] release];108}109 110 111@interface rdar12415065 : NSObject112@end113 114@implementation rdar12415065115- (void)test {116  // At one point this crashed because we created a path note at a117  // PreStmtPurgeDeadSymbols point but only knew how to deal with PostStmt118  // points.119 120  extern dispatch_queue_t queue;121 122  if (!queue)123    return;124 125  // This previously was a false positive with 'x' being flagged as being126  // uninitialized when captured by the exterior block (when it is only127  // captured by the interior block).128  dispatch_async(queue, ^{129    double x = 0.0;130    if (24.0f < x) {131      dispatch_async(queue, ^{ (void)x; });132      [self test];133    }134  });135}136@end137 138void testReturnVariousSignatures(void) {139  (void)^int(void){140    return 42;141  }();142 143  (void)^int{144    return 42;145  }();146 147  (void)^(void){148    return 42;149  }();150 151  (void)^{152    return 42;153  }();154}155 156// This test used to cause infinite loop in the region invalidation.157void blockCapturesItselfInTheLoop(int x, int m) {158  void (^assignData)(int) = ^(int x){159    x++;160  };161  while (m < 0) {162    void (^loop)(int);163    loop = ^(int x) {164      assignData(x);165    };166    assignData = loop;167    m++;168  }169  assignData(x);170}171 172// Blocks that called the function they were contained in that also have173// static locals caused crashes.174void takeNonnullBlock(void (^)(void)) __attribute__((nonnull));175void takeNonnullIntBlock(int (^)(void)) __attribute__((nonnull));176 177void testCallContainingWithSignature1(void)178{179  takeNonnullBlock(^{180    static const char str[] = "Lost connection to sharingd";181    testCallContainingWithSignature1();182  });183}184 185void testCallContainingWithSignature2(void)186{187  takeNonnullBlock(^void{188    static const char str[] = "Lost connection to sharingd";189    testCallContainingWithSignature2();190  });191}192 193void testCallContainingWithSignature3(void)194{195  takeNonnullBlock(^void(void){196    static const char str[] = "Lost connection to sharingd";197    testCallContainingWithSignature3();198  });199}200 201void testCallContainingWithSignature4(void)202{203  takeNonnullBlock(^void(void){204    static const char str[] = "Lost connection to sharingd";205    testCallContainingWithSignature4();206  });207}208 209void testCallContainingWithSignature5(void)210{211  takeNonnullIntBlock(^{212    static const char str[] = "Lost connection to sharingd";213    testCallContainingWithSignature5();214    return 0;215  });216}217 218__attribute__((objc_root_class))219@interface SuperClass220- (void)someMethod;221@end222 223@interface SomeClass : SuperClass224@end225 226// Make sure to properly handle super-calls when a block captures227// a local variable named 'self'.228@implementation SomeClass229-(void)foo; {230  /*__weak*/ SomeClass *weakSelf = self;231  (void)(^(void) {232    SomeClass *self = weakSelf;233    (void)(^(void) {234      (void)self;235      [super someMethod]; // no-warning236    });237  });238}239@end240 241// The incorrect block variable initialization below is a hard compile-time242// error in C++.243#if !defined(__cplusplus)244void call_block_with_fewer_arguments(void) {245  void (^b)() = ^(int a) { };246  b(); // expected-warning {{Block taking 1 argument is called with fewer (0)}}247}248#endif249 250int getBlockFlags(void) {251  int x = 0;252  return ((struct Block_layout *)^{ (void)x; })->flags; // no-warning253}254