brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · d2b8e7b Raw
144 lines · plain
1// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -Wno-objc-root-class -analyzer-checker=core,deadcode,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s2 3int clang_analyzer_eval(int);4 5@interface Super6- (void)superMethod;7@end8 9@interface Sub : Super {10  int _ivar1;11  int _ivar2;12}13@end14 15@implementation Sub16- (void)callMethodOnSuperInCXXLambda; {17  // Explicit capture.18  [self]() {19    [super superMethod];20  }();21 22  // Implicit capture.23  [=]() {24    [super superMethod];25  }();26}27 28// Make sure to properly handle super-calls when a block captures29// a local variable named 'self'.30- (void)callMethodOnSuperInCXXLambdaWithRedefinedSelf; {31  /*__weak*/ Sub *weakSelf = self;32  // Implicit capture. (Sema outlaws explicit capture of a redefined self33  // and a call to super [which uses the original self]).34  [=]() {35    Sub *self = weakSelf;36    [=]() {37      [super superMethod];38    }();39  }();40}41 42- (void)swapIvars {43  int tmp = _ivar1;44  _ivar1 = _ivar2;45  _ivar2 = tmp;46}47 48- (void)callMethodOnSelfInCXXLambda; {49  _ivar1 = 7;50  _ivar2 = 8;51  [self]() {52    [self swapIvars];53  }();54 55  clang_analyzer_eval(_ivar1 == 8); // expected-warning{{TRUE}}56  clang_analyzer_eval(_ivar2 == 7); // expected-warning{{TRUE}}57}58 59@end60 61int getValue();62void useValue(int v);63 64void castToBlockNoDeadStore() {65  int v = getValue(); // no-warning66 67  (void)(void(^)())[v]() { // This capture should count as a use, so no dead store warning above.68  };69}70 71void takesBlock(void(^block)());72 73void passToFunctionTakingBlockNoDeadStore() {74  int v = 7; // no-warning75  int x = 8; // no-warning76  takesBlock([&v, x]() {77    (void)v;78  });79}80 81void castToBlockAndInline() {82  int result = ((int(^)(int))[](int p) {83    return p;84  })(7);85 86  clang_analyzer_eval(result == 7); // expected-warning{{TRUE}}87}88 89void castToBlockWithCaptureAndInline() {90  int y = 7;91 92  auto lambda = [y]{ return y; };93  int(^block)() = lambda;94 95  int result = block();96  clang_analyzer_eval(result == 7); // expected-warning{{TRUE}}97}98 99void castMutableLambdaToBlock() {100  int x = 0;101 102  auto lambda = [x]() mutable {103    x = x + 1;104    return x;105   };106 107  // The block should copy the lambda before capturing.108  int(^block)() = lambda;109 110  int r1 = block();111  clang_analyzer_eval(r1 == 1); // expected-warning{{TRUE}}112 113  int r2 = block();114  clang_analyzer_eval(r2 == 2); // expected-warning{{TRUE}}115 116  // Because block copied the lambda, r3 should be 1.117  int r3 = lambda();118  clang_analyzer_eval(r3 == 1); // expected-warning{{TRUE}}119 120  // Aliasing the block shouldn't copy the lambda.121  int(^blockAlias)() = block;122 123  int r4 = blockAlias();124  clang_analyzer_eval(r4 == 3); // expected-warning{{TRUE}}125 126  int r5 = block();127  clang_analyzer_eval(r5 == 4); // expected-warning{{TRUE}}128 129  // Another copy of lambda130  int(^blockSecondCopy)() = lambda;131  int r6 = blockSecondCopy();132  clang_analyzer_eval(r6 == 2); // expected-warning{{TRUE}}133}134 135void castLambdaInLocalBlock() {136  // Make sure we don't emit a spurious diagnostic about the address of a block137  // escaping in the implicit conversion operator method for lambda-to-block138  // conversions.139  auto lambda = []{ }; // no-warning140 141  void(^block)() = lambda;142  (void)block;143}144