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 %s
3 int clang_analyzer_eval(int);
9 @interface Sub : Super {
16 - (void)callMethodOnSuperInCXXLambda; {
28 // Make sure to properly handle super-calls when a block captures
29 // a local variable named 'self'.
30 - (void)callMethodOnSuperInCXXLambdaWithRedefinedSelf; {
31 /*__weak*/ Sub *weakSelf = self;
32 // Implicit capture. (Sema outlaws explicit capture of a redefined self
33 // and a call to super [which uses the original self]).
48 - (void)callMethodOnSelfInCXXLambda; {
55 clang_analyzer_eval(_ivar1 == 8); // expected-warning{{TRUE}}
56 clang_analyzer_eval(_ivar2 == 7); // expected-warning{{TRUE}}
64 void castToBlockNoDeadStore() {
65 int v = getValue(); // no-warning
67 (void)(void(^)())[v]() { // This capture should count as a use, so no dead store warning above.
71 void takesBlock(void(^block)());
73 void passToFunctionTakingBlockNoDeadStore() {
74 int v = 7; // no-warning
75 int x = 8; // no-warning
76 takesBlock([&v, x]() {
81 void castToBlockAndInline() {
82 int result = ((int(^)(int))[](int p) {
86 clang_analyzer_eval(result == 7); // expected-warning{{TRUE}}
89 void castToBlockWithCaptureAndInline() {
92 auto lambda = [y]{ return y; };
93 int(^block)() = lambda;
96 clang_analyzer_eval(result == 7); // expected-warning{{TRUE}}
99 void castMutableLambdaToBlock() {
102 auto lambda = [x]() mutable {
107 // The block should copy the lambda before capturing.
108 int(^block)() = lambda;
111 clang_analyzer_eval(r1 == 1); // expected-warning{{TRUE}}
114 clang_analyzer_eval(r2 == 2); // expected-warning{{TRUE}}
116 // Because block copied the lambda, r3 should be 1.
118 clang_analyzer_eval(r3 == 1); // expected-warning{{TRUE}}
120 // Aliasing the block shouldn't copy the lambda.
121 int(^blockAlias)() = block;
123 int r4 = blockAlias();
124 clang_analyzer_eval(r4 == 3); // expected-warning{{TRUE}}
127 clang_analyzer_eval(r5 == 4); // expected-warning{{TRUE}}
129 // Another copy of lambda
130 int(^blockSecondCopy)() = lambda;
131 int r6 = blockSecondCopy();
132 clang_analyzer_eval(r6 == 2); // expected-warning{{TRUE}}
135 void castLambdaInLocalBlock() {
136 // Make sure we don't emit a spurious diagnostic about the address of a block
137 // escaping in the implicit conversion operator method for lambda-to-block
139 auto lambda = []{ }; // no-warning
141 void(^block)() = lambda;