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