xref: /llvm-project/clang/test/Analysis/symbol-reaper-lambda.cpp (revision 73716baa30ebc75783d2902e12accea35dec193a)
1*73716baaSTomasz Kamiński // RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
2*73716baaSTomasz Kamiński // expected-no-diagnostics
3*73716baaSTomasz Kamiński 
4*73716baaSTomasz Kamiński template <typename... Ts>
5*73716baaSTomasz Kamiński void escape(Ts&...);
6*73716baaSTomasz Kamiński struct Dummy {};
7*73716baaSTomasz Kamiński 
strange(Dummy param)8*73716baaSTomasz Kamiński int strange(Dummy param) {
9*73716baaSTomasz Kamiński   Dummy local_pre_lambda;
10*73716baaSTomasz Kamiński   int ref_captured = 0;
11*73716baaSTomasz Kamiński 
12*73716baaSTomasz Kamiński   // LambdaExpr is modeled as lazyCompoundVal of tempRegion, that contains
13*73716baaSTomasz Kamiński   // all captures. In this instance, this region contains a pointer/reference
14*73716baaSTomasz Kamiński   // to ref_captured variable.
15*73716baaSTomasz Kamiński   auto fn = [&] {
16*73716baaSTomasz Kamiński     escape(param, local_pre_lambda);
17*73716baaSTomasz Kamiński     return ref_captured; // no-warning: The value is not garbage.
18*73716baaSTomasz Kamiński   };
19*73716baaSTomasz Kamiński 
20*73716baaSTomasz Kamiński   int local_defined_after_lambda; // Unused, but necessary! Important that it's before the call.
21*73716baaSTomasz Kamiński 
22*73716baaSTomasz Kamiński   // The ref_captured binding should not be pruned at this point, as it is still
23*73716baaSTomasz Kamiński   // accessed via reference captured in operator() of fn.
24*73716baaSTomasz Kamiński   return fn();
25*73716baaSTomasz Kamiński }
26*73716baaSTomasz Kamiński 
27