[clang-tidy] Fix `readability-container-size-empty` check for smart pointers

Fixes https://github.com/llvm/llvm-project/issues/51118.

Reviewed By: Sockke

Differential Revision: https://reviews.llvm.org/D115124
This commit is contained in:
Fabian Wolff 2022-04-20 17:03:30 +02:00
parent f25935a000
commit fb3b3f76bf
3 changed files with 34 additions and 2 deletions

View File

@ -191,10 +191,17 @@ void ContainerSizeEmptyCheck::check(const MatchFinder::MatchResult &Result) {
std::string ReplacementText = std::string(
Lexer::getSourceText(CharSourceRange::getTokenRange(E->getSourceRange()),
*Result.SourceManager, getLangOpts()));
if (isBinaryOrTernary(E) || isa<UnaryOperator>(E)) {
const auto *OpCallExpr = dyn_cast<CXXOperatorCallExpr>(E);
if (isBinaryOrTernary(E) || isa<UnaryOperator>(E) ||
(OpCallExpr && (OpCallExpr->getOperator() == OO_Star))) {
ReplacementText = "(" + ReplacementText + ")";
}
if (E->getType()->isPointerType())
if (OpCallExpr &&
OpCallExpr->getOperator() == OverloadedOperatorKind::OO_Arrow) {
// This can happen if the object is a smart pointer. Don't add anything
// because a '->' is already there (PR#51776), just call the method.
ReplacementText += "empty()";
} else if (E->getType()->isPointerType())
ReplacementText += "->empty()";
else
ReplacementText += ".empty()";

View File

@ -173,6 +173,9 @@ Changes in existing checks
- Fixed nonsensical suggestion of :doc:`altera-struct-pack-align
<clang-tidy/checks/altera-struct-pack-align>` check for empty structs.
- Fixed incorrect suggestions for :doc:`readability-container-size-empty
<clang-tidy/checks/readability-container-size-empty>` when smart pointers are involved.
Removed checks
^^^^^^^^^^^^^^

View File

@ -696,3 +696,25 @@ void instantiator() {
instantiatedTemplateWithSizeCall<TypeWithSize>();
instantiatedTemplateWithSizeCall<std::vector<int>>();
}
namespace std {
template <typename T>
struct unique_ptr {
T *operator->() const;
T &operator*() const;
};
} // namespace std
bool call_through_unique_ptr(const std::unique_ptr<std::vector<int>> &ptr) {
return ptr->size() > 0;
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used
// CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
// CHECK-FIXES: {{^ }}return !ptr->empty();
}
bool call_through_unique_ptr_deref(const std::unique_ptr<std::vector<int>> &ptr) {
return (*ptr).size() > 0;
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used
// CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
// CHECK-FIXES: {{^ }}return !(*ptr).empty();
}