1 // RUN: %clang_cc1 -fsyntax-only -Wunused-lambda-capture -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++1z %s 2 3 class NonTrivialConstructor { 4 public: NonTrivialConstructor()5 NonTrivialConstructor() {} 6 }; 7 8 class NonTrivialCopyConstructor { 9 public: 10 NonTrivialCopyConstructor() = default; NonTrivialCopyConstructor(const NonTrivialCopyConstructor &)11 NonTrivialCopyConstructor(const NonTrivialCopyConstructor &) {} 12 }; 13 14 class NonTrivialDestructor { 15 public: ~NonTrivialDestructor()16 ~NonTrivialDestructor() {} 17 }; 18 19 class Trivial { 20 public: 21 Trivial() = default; Trivial(int a)22 Trivial(int a) {} 23 }; 24 side_effect()25int side_effect() { 26 return 42; 27 } 28 test()29void test() { 30 int i = 0; 31 const int k = 0; 32 33 auto captures_nothing = [] {}; 34 35 auto captures_nothing_by_value = [=] {}; 36 auto captures_nothing_by_reference = [&] {}; 37 38 auto implicit_by_value = [=]() mutable { i++; }; 39 auto implicit_by_reference = [&] { i++; }; 40 41 auto explicit_by_value_used = [i] { return i + 1; }; 42 auto explicit_by_value_used_void = [i] { (void)i; }; 43 auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}} 44 auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}} 45 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}} 46 auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} 47 48 auto explicit_by_reference_used = [&i] { i++; }; 49 auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}} 50 51 auto explicit_initialized_reference_used = [&j = i] { return j + 1; }; 52 auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}} 53 54 auto explicit_initialized_value_used = [j = 1] { return j + 1; }; 55 auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}} 56 auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{}; 57 auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{}; 58 auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}} 59 auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{}; 60 auto explicit_initialized_value_with_side_effect = [j = side_effect()]{}; 61 62 auto nested = [&i] { 63 auto explicit_by_value_used = [i] { return i + 1; }; 64 auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}} 65 }; 66 67 Trivial trivial; 68 auto explicit_by_value_trivial = [trivial] {}; // expected-warning{{lambda capture 'trivial' is not used}} 69 70 NonTrivialConstructor cons; 71 auto explicit_by_value_non_trivial_constructor = [cons] {}; // expected-warning{{lambda capture 'cons' is not used}} 72 73 NonTrivialCopyConstructor copy_cons; 74 auto explicit_by_value_non_trivial_copy_constructor = [copy_cons] {}; 75 76 NonTrivialDestructor dest; 77 auto explicit_by_value_non_trivial_destructor = [dest] {}; 78 79 volatile int v; 80 auto explicit_by_value_volatile = [v] {}; 81 } 82 83 class TrivialThis : Trivial { test()84 void test() { 85 auto explicit_this_used = [this] { return i; }; 86 auto explicit_this_used_void = [this] { (void)this; }; 87 auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}} 88 auto explicit_star_this_used = [*this] { return i; }; 89 auto explicit_star_this_used_void = [*this] { (void)this; }; 90 auto explicit_star_this_unused = [*this] {}; // expected-warning{{lambda capture 'this' is not used}} 91 } 92 int i; 93 }; 94 95 class NonTrivialConstructorThis : NonTrivialConstructor { test()96 void test() { 97 auto explicit_this_used = [this] { return i; }; 98 auto explicit_this_used_void = [this] { (void)this; }; 99 auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}} 100 auto explicit_star_this_used = [*this] { return i; }; 101 auto explicit_star_this_used_void = [*this] { (void)this; }; 102 auto explicit_star_this_unused = [*this] {}; // expected-warning{{lambda capture 'this' is not used}} 103 } 104 int i; 105 }; 106 107 class NonTrivialCopyConstructorThis : NonTrivialCopyConstructor { test()108 void test() { 109 auto explicit_this_used = [this] { return i; }; 110 auto explicit_this_used_void = [this] { (void)this; }; 111 auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}} 112 auto explicit_star_this_used = [*this] { return i; }; 113 auto explicit_star_this_used_void = [*this] { (void)this; }; 114 auto explicit_star_this_unused = [*this] {}; 115 } 116 int i; 117 }; 118 119 class NonTrivialDestructorThis : NonTrivialDestructor { test()120 void test() { 121 auto explicit_this_used = [this] { return i; }; 122 auto explicit_this_used_void = [this] { (void)this; }; 123 auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}} 124 auto explicit_star_this_used = [*this] { return i; }; 125 auto explicit_star_this_used_void = [*this] { (void)this; }; 126 auto explicit_star_this_unused = [*this] {}; 127 } 128 int i; 129 }; 130 131 template <typename T> test_templated()132void test_templated() { 133 int i = 0; 134 const int k = 0; 135 136 auto captures_nothing = [] {}; 137 138 auto captures_nothing_by_value = [=] {}; 139 auto captures_nothing_by_reference = [&] {}; 140 141 auto implicit_by_value = [=]() mutable { i++; }; 142 auto implicit_by_reference = [&] { i++; }; 143 144 auto explicit_by_value_used = [i] { return i + 1; }; 145 auto explicit_by_value_used_generic = [i](auto c) { return i + 1; }; 146 auto explicit_by_value_used_void = [i] { (void)i; }; 147 148 auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}} 149 auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}} 150 auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}} 151 auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} 152 auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}} 153 154 auto explicit_by_reference_used = [&i] { i++; }; 155 auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}} 156 157 auto explicit_initialized_reference_used = [&j = i] { return j + 1; }; 158 auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}} 159 160 auto explicit_initialized_value_used = [j = 1] { return j + 1; }; 161 auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}} 162 auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{}; 163 auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{}; 164 auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}} 165 auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{}; 166 auto explicit_initialized_value_with_side_effect = [j = side_effect()]{}; 167 auto explicit_initialized_value_generic_used = [i = 1](auto c) mutable { i++; }; 168 auto explicit_initialized_value_generic_unused = [i = 1](auto c) mutable {}; // expected-warning{{lambda capture 'i' is not used}} 169 170 auto nested = [&i] { 171 auto explicit_by_value_used = [i] { return i + 1; }; 172 auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}} 173 }; 174 175 Trivial trivial; 176 auto explicit_by_value_trivial = [trivial] {}; // expected-warning{{lambda capture 'trivial' is not used}} 177 178 NonTrivialConstructor cons; 179 auto explicit_by_value_non_trivial_constructor = [cons] {}; // expected-warning{{lambda capture 'cons' is not used}} 180 181 NonTrivialCopyConstructor copy_cons; 182 auto explicit_by_value_non_trivial_copy_constructor = [copy_cons] {}; 183 184 NonTrivialDestructor dest; 185 auto explicit_by_value_non_trivial_destructor = [dest] {}; 186 187 volatile int v; 188 auto explicit_by_value_volatile = [v] {}; 189 } 190 test_use_template()191void test_use_template() { 192 test_templated<int>(); // expected-note{{in instantiation of function template specialization 'test_templated<int>' requested here}} 193 } 194 195 namespace pr35555 { 196 int a; b()197void b() { 198 int c[a]; 199 auto vla_used = [&c] { return c[0]; }; 200 auto vla_unused = [&c] {}; // expected-warning{{lambda capture 'c' is not used}} 201 } 202 } // namespace pr35555 203