aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/warn-unused-lambda-capture.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/warn-unused-lambda-capture.cpp')
-rw-r--r--test/SemaCXX/warn-unused-lambda-capture.cpp188
1 files changed, 188 insertions, 0 deletions
diff --git a/test/SemaCXX/warn-unused-lambda-capture.cpp b/test/SemaCXX/warn-unused-lambda-capture.cpp
new file mode 100644
index 000000000000..48f8bfea7e9a
--- /dev/null
+++ b/test/SemaCXX/warn-unused-lambda-capture.cpp
@@ -0,0 +1,188 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-lambda-capture -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++1z %s
+
+class NonTrivialConstructor {
+public:
+ NonTrivialConstructor() {}
+};
+
+class NonTrivialCopyConstructor {
+public:
+ NonTrivialCopyConstructor() = default;
+ NonTrivialCopyConstructor(const NonTrivialCopyConstructor &) {}
+};
+
+class NonTrivialDestructor {
+public:
+ ~NonTrivialDestructor() {}
+};
+
+class Trivial {
+public:
+ Trivial() = default;
+ Trivial(int a) {}
+};
+
+int side_effect() {
+ return 42;
+}
+
+void test() {
+ int i = 0;
+ const int k = 0;
+
+ auto captures_nothing = [] {};
+
+ auto captures_nothing_by_value = [=] {};
+ auto captures_nothing_by_reference = [&] {};
+
+ auto implicit_by_value = [=]() mutable { i++; };
+ auto implicit_by_reference = [&] { i++; };
+
+ auto explicit_by_value_used = [i] { return i + 1; };
+ auto explicit_by_value_used_void = [i] { (void)i; };
+ auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
+ auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
+ 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}}
+ auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
+
+ auto explicit_by_reference_used = [&i] { i++; };
+ auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
+
+ auto explicit_initialized_reference_used = [&j = i] { return j + 1; };
+ auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}}
+
+ auto explicit_initialized_value_used = [j = 1] { return j + 1; };
+ auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}}
+ auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{};
+ auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{};
+ auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}}
+ auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{};
+ auto explicit_initialized_value_with_side_effect = [j = side_effect()]{};
+
+ auto nested = [&i] {
+ auto explicit_by_value_used = [i] { return i + 1; };
+ auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
+ };
+
+ Trivial trivial;
+ auto explicit_by_value_trivial = [trivial] {}; // expected-warning{{lambda capture 'trivial' is not used}}
+
+ NonTrivialConstructor cons;
+ auto explicit_by_value_non_trivial_constructor = [cons] {}; // expected-warning{{lambda capture 'cons' is not used}}
+
+ NonTrivialCopyConstructor copy_cons;
+ auto explicit_by_value_non_trivial_copy_constructor = [copy_cons] {};
+
+ NonTrivialDestructor dest;
+ auto explicit_by_value_non_trivial_destructor = [dest] {};
+
+ volatile int v;
+ auto explicit_by_value_volatile = [v] {};
+}
+
+class TrivialThis : Trivial {
+ void test() {
+ auto explicit_this_used = [this] { return i; };
+ auto explicit_this_used_void = [this] { (void)this; };
+ auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
+ auto explicit_star_this_used = [*this] { return i; };
+ auto explicit_star_this_used_void = [*this] { (void)this; };
+ auto explicit_star_this_unused = [*this] {}; // expected-warning{{lambda capture 'this' is not used}}
+ }
+ int i;
+};
+
+class NonTrivialConstructorThis : NonTrivialConstructor {
+ void test() {
+ auto explicit_this_used = [this] { return i; };
+ auto explicit_this_used_void = [this] { (void)this; };
+ auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
+ auto explicit_star_this_used = [*this] { return i; };
+ auto explicit_star_this_used_void = [*this] { (void)this; };
+ auto explicit_star_this_unused = [*this] {}; // expected-warning{{lambda capture 'this' is not used}}
+ }
+ int i;
+};
+
+class NonTrivialCopyConstructorThis : NonTrivialCopyConstructor {
+ void test() {
+ auto explicit_this_used = [this] { return i; };
+ auto explicit_this_used_void = [this] { (void)this; };
+ auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
+ auto explicit_star_this_used = [*this] { return i; };
+ auto explicit_star_this_used_void = [*this] { (void)this; };
+ auto explicit_star_this_unused = [*this] {};
+ }
+ int i;
+};
+
+class NonTrivialDestructorThis : NonTrivialDestructor {
+ void test() {
+ auto explicit_this_used = [this] { return i; };
+ auto explicit_this_used_void = [this] { (void)this; };
+ auto explicit_this_unused = [this] {}; // expected-warning{{lambda capture 'this' is not used}}
+ auto explicit_star_this_used = [*this] { return i; };
+ auto explicit_star_this_used_void = [*this] { (void)this; };
+ auto explicit_star_this_unused = [*this] {};
+ }
+ int i;
+};
+
+template <typename T>
+void test_templated() {
+ int i = 0;
+ const int k = 0;
+
+ auto captures_nothing = [] {};
+
+ auto captures_nothing_by_value = [=] {};
+ auto captures_nothing_by_reference = [&] {};
+
+ auto implicit_by_value = [=]() mutable { i++; };
+ auto implicit_by_reference = [&] { i++; };
+
+ auto explicit_by_value_used = [i] { return i + 1; };
+ auto explicit_by_value_used_void = [i] { (void)i; };
+ auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
+ auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
+ auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}}
+ auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
+
+ auto explicit_by_reference_used = [&i] { i++; };
+ auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
+
+ auto explicit_initialized_reference_used = [&j = i] { return j + 1; };
+ auto explicit_initialized_reference_unused = [&j = i]{}; // expected-warning{{lambda capture 'j' is not used}}
+
+ auto explicit_initialized_value_used = [j = 1] { return j + 1; };
+ auto explicit_initialized_value_unused = [j = 1] {}; // expected-warning{{lambda capture 'j' is not used}}
+ auto explicit_initialized_value_non_trivial_constructor = [j = NonTrivialConstructor()]{};
+ auto explicit_initialized_value_non_trivial_destructor = [j = NonTrivialDestructor()]{};
+ auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}}
+ auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{};
+ auto explicit_initialized_value_with_side_effect = [j = side_effect()]{};
+
+ auto nested = [&i] {
+ auto explicit_by_value_used = [i] { return i + 1; };
+ auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
+ };
+
+ Trivial trivial;
+ auto explicit_by_value_trivial = [trivial] {}; // expected-warning{{lambda capture 'trivial' is not used}}
+
+ NonTrivialConstructor cons;
+ auto explicit_by_value_non_trivial_constructor = [cons] {}; // expected-warning{{lambda capture 'cons' is not used}}
+
+ NonTrivialCopyConstructor copy_cons;
+ auto explicit_by_value_non_trivial_copy_constructor = [copy_cons] {};
+
+ NonTrivialDestructor dest;
+ auto explicit_by_value_non_trivial_destructor = [dest] {};
+
+ volatile int v;
+ auto explicit_by_value_volatile = [v] {};
+}
+
+void test_use_template() {
+ test_templated<int>(); // expected-note{{in instantiation of function template specialization 'test_templated<int>' requested here}}
+}