blob: 15100be32d671e2103cc46c22b6101e372749ffc [file] [log] [blame]
Gabor Horvath15843342015-09-11 16:55:01 +00001// RUN: %clang_cc1 -std=c++11 -fsyntax-only -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s
2// RUN: %clang_cc1 -std=c++11 -fsyntax-only -analyze -analyzer-checker=core,debug.DumpCFG -analyzer-config inline-lambdas=true %s > %t 2>&1
Ted Kremenekda76a942012-04-12 20:34:52 +00003// RUN: FileCheck --input-file=%t %s
4
Gabor Horvath15843342015-09-11 16:55:01 +00005void clang_analyzer_warnIfReached();
6void clang_analyzer_eval(int);
7
Ted Kremenekda76a942012-04-12 20:34:52 +00008struct X { X(const X&); };
9void f(X x) { (void) [x]{}; }
10
Gabor Horvath15843342015-09-11 16:55:01 +000011
12// Lambda semantics tests.
13
14void basicCapture() {
15 int i = 5;
16 [i]() mutable {
17 // clang_analyzer_eval does nothing in inlined functions.
18 if (i != 5)
19 clang_analyzer_warnIfReached();
20 ++i;
21 }();
22 [&i] {
23 if (i != 5)
24 clang_analyzer_warnIfReached();
25 }();
26 [&i] {
27 if (i != 5)
28 clang_analyzer_warnIfReached();
29 i++;
30 }();
31 clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
32}
33
34void deferredLambdaCall() {
35 int i = 5;
36 auto l1 = [i]() mutable {
37 if (i != 5)
38 clang_analyzer_warnIfReached();
39 ++i;
40 };
41 auto l2 = [&i] {
42 if (i != 5)
43 clang_analyzer_warnIfReached();
44 };
45 auto l3 = [&i] {
46 if (i != 5)
47 clang_analyzer_warnIfReached();
48 i++;
49 };
50 l1();
51 l2();
52 l3();
53 clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
54}
55
56void multipleCaptures() {
57 int i = 5, j = 5;
58 [i, &j]() mutable {
59 if (i != 5 && j != 5)
60 clang_analyzer_warnIfReached();
61 ++i;
62 ++j;
63 }();
64 clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
65 clang_analyzer_eval(j == 6); // expected-warning{{TRUE}}
66 [=]() mutable {
67 if (i != 5 && j != 6)
68 clang_analyzer_warnIfReached();
69 ++i;
70 ++j;
71 }();
72 clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
73 clang_analyzer_eval(j == 6); // expected-warning{{TRUE}}
74 [&]() mutable {
75 if (i != 5 && j != 6)
76 clang_analyzer_warnIfReached();
77 ++i;
78 ++j;
79 }();
80 clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
81 clang_analyzer_eval(j == 7); // expected-warning{{TRUE}}
82}
83
84void testReturnValue() {
85 int i = 5;
86 auto l = [i] (int a) {
87 return i + a;
88 };
89 int b = l(3);
90 clang_analyzer_eval(b == 8); // expected-warning{{TRUE}}
91}
92
93// Nested lambdas.
94
95void testNestedLambdas() {
96 int i = 5;
97 auto l = [i]() mutable {
98 [&i]() {
99 ++i;
100 }();
101 if (i != 6)
102 clang_analyzer_warnIfReached();
103 };
104 l();
105 clang_analyzer_eval(i == 5); // expected-warning{{TRUE}}
106}
107
108// Captured this.
109
110class RandomClass {
111 int i;
112
113 void captureFields() {
114 i = 5;
115 [this]() {
116 // clang_analyzer_eval does nothing in inlined functions.
117 if (i != 5)
118 clang_analyzer_warnIfReached();
119 ++i;
120 }();
121 clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
122 }
123};
124
125
126// Nested this capture.
127
128class RandomClass2 {
129 int i;
130
131 void captureFields() {
132 i = 5;
133 [this]() {
134 // clang_analyzer_eval does nothing in inlined functions.
135 if (i != 5)
136 clang_analyzer_warnIfReached();
137 ++i;
138 [this]() {
139 // clang_analyzer_eval does nothing in inlined functions.
140 if (i != 6)
141 clang_analyzer_warnIfReached();
142 ++i;
143 }();
144 }();
145 clang_analyzer_eval(i == 7); // expected-warning{{TRUE}}
146 }
147};
148
149
150// Captured function pointers.
151
152void inc(int &x) {
153 ++x;
154}
155
156void testFunctionPointerCapture() {
157 void (*func)(int &) = inc;
158 int i = 5;
159 [&i, func] {
160 func(i);
161 }();
162 clang_analyzer_eval(i == 6); // expected-warning{{TRUE}}
163}
164
165
166// Test inline defensive checks
167int getNum();
168
169void inlineDefensiveChecks() {
170 int i = getNum();
171 [=]() {
172 if (i == 0)
173 ;
174 }();
175 int p = 5/i;
176 (void)p;
177}
178
Ted Kremenekda76a942012-04-12 20:34:52 +0000179// CHECK: [B2 (ENTRY)]
180// CHECK: Succs (1): B1
181// CHECK: [B1]
182// CHECK: 1: x
183// CHECK: 2: [B1.1] (ImplicitCastExpr, NoOp, const struct X)
184// CHECK: 3: [B1.2] (CXXConstructExpr, struct X)
Richard Smithbb13c9a2013-09-28 04:02:39 +0000185// CHECK: 4: [x] {
Ted Kremenekda76a942012-04-12 20:34:52 +0000186// CHECK: }
187// CHECK: 5: (void)[B1.4] (CStyleCastExpr, ToVoid, void)
188// CHECK: Preds (1): B2
189// CHECK: Succs (1): B0
190// CHECK: [B0 (EXIT)]
191// CHECK: Preds (1): B1
192