// RUN: %check_clang_tidy %s bugprone-standalone-empty %t namespace std { template struct vector { bool empty(); }; template struct vector_with_clear { bool empty(); void clear(); }; template struct vector_with_void_empty { void empty(); void clear(); }; template struct vector_with_int_empty { int empty(); void clear(); }; template struct vector_with_clear_args { bool empty(); void clear(int i); }; template struct vector_with_clear_variable { bool empty(); int clear; }; template bool empty(T &&); } // namespace std namespace absl { struct string { bool empty(); }; struct string_with_clear { bool empty(); void clear(); }; struct string_with_void_empty { void empty(); void clear(); }; struct string_with_int_empty { int empty(); void clear(); }; struct string_with_clear_args { bool empty(); void clear(int i); }; struct string_with_clear_variable { bool empty(); int clear; }; template bool empty(T &&); } // namespace absl namespace test { template void empty(T &&); } // namespace test namespace test_no_args { bool empty(); } // namespace test_no_args namespace base { template struct base_vector { void clear(); }; template struct base_vector_clear_with_args { void clear(int i); }; template struct base_vector_clear_variable { int clear; }; struct base_vector_non_dependent { void clear(); }; template struct vector : base_vector { bool empty(); }; template struct vector_clear_with_args : base_vector_clear_with_args { bool empty(); }; template struct vector_clear_variable : base_vector_clear_variable { bool empty(); }; template struct vector_non_dependent : base_vector_non_dependent { bool empty(); }; template bool empty(T &&); } // namespace base namespace qualifiers { template struct vector_with_const_clear { bool empty() const; void clear() const; }; template struct vector_with_const_empty { bool empty() const; void clear(); }; template struct vector_with_volatile_clear { bool empty() volatile; void clear() volatile; }; template struct vector_with_volatile_empty { bool empty() volatile; void clear(); }; template bool empty(T &&); } // namespace qualifiers bool test_member_empty() { { std::vector v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { std::vector_with_void_empty v; v.empty(); // no-warning } { std::vector_with_clear v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { std::vector_with_int_empty v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { std::vector_with_clear_args v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { std::vector_with_clear_variable v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { absl::string s; s.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { absl::string_with_void_empty s; s.empty(); // no-warning } { absl::string_with_clear s; s.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} s.clear();{{$}} } { absl::string_with_int_empty s; s.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} s.clear();{{$}} } { absl::string_with_clear_args s; s.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { absl::string_with_clear_variable s; s.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { std::vector v; return v.empty(); // no-warning } { std::vector_with_clear v; return v.empty(); // no-warning } { std::vector_with_int_empty v; return v.empty(); // no-warning } { std::vector_with_clear_args v; return v.empty(); // no-warning } { std::vector_with_clear_variable v; return v.empty(); // no-warning } { absl::string s; return s.empty(); // no-warning } { absl::string_with_clear s; return s.empty(); // no-warning } { absl::string_with_int_empty s; return s.empty(); // no-warning } { absl::string_with_clear_args s; return s.empty(); // no-warning } { absl::string_with_clear_variable s; return s.empty(); // no-warning } } bool test_qualified_empty() { { absl::string_with_clear v; std::empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} absl::empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'absl::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} test::empty(v); // no-warning test_no_args::empty(); // no-warning } { absl::string s; std::empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] } { std::empty(0); // no-warning absl::empty(nullptr); // no-warning } { absl::string_with_clear s; return std::empty(s); // no-warning return absl::empty(s); // no-warning } { absl::string s; return std::empty(s); // no-warning } { return std::empty(0); // no-warning return absl::empty(nullptr); // no-warning } } bool test_unqualified_empty() { { std::vector v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] } { std::vector_with_void_empty v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { std::vector_with_clear v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { std::vector_with_int_empty v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { std::vector_with_clear_args v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] } { std::vector_with_clear_variable v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] } { absl::string s; empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'absl::empty' [bugprone-standalone-empty] } { absl::string_with_void_empty s; empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'absl::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} s.clear();{{$}} } { absl::string_with_clear s; empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'absl::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} s.clear();{{$}} } { absl::string_with_int_empty s; empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'absl::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} s.clear();{{$}} } { absl::string_with_clear_args s; empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'absl::empty' [bugprone-standalone-empty] } { absl::string_with_clear_variable s; empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'absl::empty' [bugprone-standalone-empty] } { std::vector v; using std::empty; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] } { std::vector_with_clear v; using std::empty; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { absl::string s; using absl::empty; empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'absl::empty' [bugprone-standalone-empty] } { absl::string_with_clear s; using absl::empty; empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'absl::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} s.clear();{{$}} } { std::vector v; return empty(v); // no-warning } { std::vector_with_void_empty v; return empty(v); // no-warning } { std::vector_with_clear v; return empty(v); // no-warning } { std::vector_with_int_empty v; return empty(v); // no-warning } { std::vector_with_clear_args v; return empty(v); // no-warning } { std::vector_with_clear_variable v; return empty(v); // no-warning } { absl::string s; return empty(s); // no-warning } { absl::string_with_void_empty s; return empty(s); // no-warning } { absl::string_with_clear s; return empty(s); // no-warning } { absl::string_with_int_empty s; return empty(s); // no-warning } { absl::string_with_clear_args s; return empty(s); // no-warning } { absl::string_with_clear_variable s; return empty(s); // no-warning } { std::vector v; using std::empty; return empty(v); // no-warning } { std::vector_with_clear v; using std::empty; return empty(v); // no-warning } { absl::string s; using absl::empty; return empty(s); // no-warning } { absl::string_with_clear s; using absl::empty; return empty(s); // no-warning } } void test_empty_method_expressions() { std::vector v; bool EmptyReturn(v.empty()); // no-warning (void)v.empty(); // no-warning // Don't warn in the if condition. if (v.empty()) v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:18: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] // Don't warn in the for condition. for(v.empty();v.empty();v.empty()) v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:7: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] // CHECK-MESSAGES: :[[#@LINE-2]]:27: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] // CHECK-MESSAGES: :[[#@LINE-3]]:38: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] // Don't warn in the while condition. while(v.empty()) v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:20: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] // Don't warn in the do-while condition. do v.empty(); while(v.empty()); // CHECK-MESSAGES: :[[#@LINE-1]]:6: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] // Don't warn in the switch expression. switch(v.empty()) { // no-warning case true: v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:7: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } // Don't warn in the return expression, which is the last statement. bool StmtExprReturn = ({v.empty(); v.empty();}); // CHECK-MESSAGES: :[[#@LINE-1]]:27: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } void test_empty_expressions() { absl::string s; bool test(std::empty(s)); // no-warning (void)std::empty(s); // no-warning if (std::empty(s)) std::empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:22: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] for(std::empty(s);std::empty(s);std::empty(s)) std::empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:7: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] // CHECK-MESSAGES: :[[#@LINE-2]]:35: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] // CHECK-MESSAGES: :[[#@LINE-3]]:50: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] while(std::empty(s)) std::empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:24: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] do std::empty(s); while(std::empty(s)); // CHECK-MESSAGES: :[[#@LINE-1]]:6: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] switch(std::empty(s)) { // no-warning case true: std::empty(s); // CHECK-MESSAGES: :[[#@LINE-1]]:7: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] } bool StmtExprReturn = ({std::empty(s); std::empty(s);}); // CHECK-MESSAGES: :[[#@LINE-1]]:27: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] } bool test_clear_in_base_class() { { base::vector v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { base::vector_non_dependent v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { base::vector_clear_with_args v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { base::vector_clear_variable v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { base::vector v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'base::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { base::vector_non_dependent v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'base::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { base::vector_clear_with_args v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'base::empty' [bugprone-standalone-empty] } { base::vector_clear_variable v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'base::empty' [bugprone-standalone-empty] } { base::vector v; return v.empty(); // no-warning } { base::vector_non_dependent v; return v.empty(); // no-warning } { base::vector_clear_with_args v; return v.empty(); // no-warning } { base::vector_clear_variable v; return v.empty(); // no-warning } { base::vector v; return empty(v); // no-warning } { base::vector_non_dependent v; return empty(v); // no-warning } { base::vector_clear_with_args v; return empty(v); // no-warning } { base::vector_clear_variable v; return empty(v); // no-warning } } bool test_clear_with_qualifiers() { { qualifiers::vector_with_const_clear v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { const qualifiers::vector_with_const_clear v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { const qualifiers::vector_with_const_empty v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { qualifiers::vector_with_const_clear v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'qualifiers::empty' [bugprone-standalone-empty] } { const qualifiers::vector_with_const_clear v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'qualifiers::empty' [bugprone-standalone-empty] } { const std::vector_with_clear v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] } { qualifiers::vector_with_volatile_clear v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { volatile qualifiers::vector_with_volatile_clear v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { volatile qualifiers::vector_with_volatile_empty v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] } { qualifiers::vector_with_volatile_clear v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'qualifiers::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { volatile qualifiers::vector_with_volatile_clear v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'qualifiers::empty'; did you mean 'clear()'? [bugprone-standalone-empty] // CHECK-FIXES: {{^ }} v.clear();{{$}} } { volatile std::vector_with_clear v; empty(v); // CHECK-MESSAGES: :[[#@LINE-1]]:5: warning: ignoring the result of 'std::empty' [bugprone-standalone-empty] } { qualifiers::vector_with_const_clear v; return v.empty(); // no-warning } { const qualifiers::vector_with_const_clear v; return v.empty(); // no-warning } { const qualifiers::vector_with_const_empty v; return v.empty(); // no-warning } { qualifiers::vector_with_const_clear v; return empty(v); // no-warning } { const qualifiers::vector_with_const_clear v; return empty(v); // no-warning } { const std::vector_with_clear v; return empty(v); // no-warning } { qualifiers::vector_with_volatile_clear v; return v.empty(); // no-warning } { volatile qualifiers::vector_with_volatile_clear v; return v.empty(); // no-warning } { volatile qualifiers::vector_with_volatile_empty v; return v.empty(); // no-warning } { qualifiers::vector_with_volatile_clear v; return empty(v); // no-warning } { volatile qualifiers::vector_with_volatile_clear v; return empty(v); // no-warning } { volatile std::vector_with_clear v; return empty(v); // no-warning } } namespace user_lib { template struct vector { bool empty(); bool test_empty_inside_impl() { empty(); // no-warning return empty(); // no-warning } }; } // namespace user_lib bool test_template_empty_outside_impl() { user_lib::vector v; v.empty(); // CHECK-MESSAGES: :[[#@LINE-1]]:3: warning: ignoring the result of 'empty()' [bugprone-standalone-empty] return v.empty(); // no-warning }