1 // RUN: %clang_cc1 -fsyntax-only -Wunused-lambda-capture -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++14 %s
2 
3 class NonTrivialConstructor {
4 public:
5   NonTrivialConstructor() {}
6 };
7 
8 class NonTrivialDestructor {
9 public:
10   ~NonTrivialDestructor() {}
11 };
12 
13 class Trivial {
14 public:
15   Trivial() = default;
16   Trivial(int a) {}
17 };
18 
19 int side_effect() {
20   return 42;
21 }
22 
23 void test() {
24   int i = 0;
25   const int k = 0;
26 
27   auto captures_nothing = [] {};
28 
29   auto captures_nothing_by_value = [=] {};
30   auto captures_nothing_by_reference = [&] {};
31 
32   auto implicit_by_value = [=]() mutable { i++; };
33   auto implicit_by_reference = [&] { i++; };
34 
35   auto explicit_by_value_used = [i] { return i + 1; };
36   auto explicit_by_value_used_void = [i] { (void)i; };
37   auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
38   auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
39   auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
40   auto explicit_by_value_unused_const = [k] { return k + 1; };         // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
41 
42   auto explicit_by_reference_used = [&i] { i++; };
43   auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
44 
45   auto explicit_initialized_reference_used = [&j = i] { return j + 1; };
46   auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}}
47 
48   auto explicit_initialized_value_used = [j = 1] { return j + 1; };
49   auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}}
50   auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{};
51   auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{};
52   auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}}
53   auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{};
54   auto explicit_initialized_value_with_side_effect = [j = side_effect()]{};
55 
56   auto nested = [&i] {
57     auto explicit_by_value_used = [i] { return i + 1; };
58     auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
59   };
60 }
61 
62 class Foo
63 {
64   void test() {
65     auto explicit_this_used = [this] { return i; };
66     auto explicit_this_used_void = [this] { (void)this; };
67     auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
68   }
69   int i;
70 };
71 
72 template <typename T>
73 void test_templated() {
74   int i = 0;
75   const int k = 0;
76 
77   auto captures_nothing = [] {};
78 
79   auto captures_nothing_by_value = [=] {};
80   auto captures_nothing_by_reference = [&] {};
81 
82   auto implicit_by_value = [=]() mutable { i++; };
83   auto implicit_by_reference = [&] { i++; };
84 
85   auto explicit_by_value_used = [i] { return i + 1; };
86   auto explicit_by_value_used_void = [i] { (void)i; };
87   auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
88   auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
89   auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}}
90   auto explicit_by_value_unused_const = [k] { return k + 1; };         // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
91 
92   auto explicit_by_reference_used = [&i] { i++; };
93   auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
94 
95   auto explicit_initialized_reference_used = [&j = i] { return j + 1; };
96   auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}}
97 
98   auto explicit_initialized_value_used = [j = 1] { return j + 1; };
99   auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}}
100   auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{};
101   auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{};
102   auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}}
103   auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{};
104   auto explicit_initialized_value_with_side_effect = [j = side_effect()]{};
105 
106   auto nested = [&i] {
107     auto explicit_by_value_used = [i] { return i + 1; };
108     auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
109   };
110 }
111 
112 void test_use_template() {
113   test_templated<int>(); // expected-note{{in instantiation of function template specialization 'test_templated<int>' requested here}}
114 }
115