fwolff created this revision.
fwolff added reviewers: mizvekov, compnerd.
fwolff added a project: clang-tools-extra.
Herald added subscribers: carlosgalvezp, xazax.hun.
fwolff requested review of this revision.
Herald added a subscriber: cfe-commits.
Fixes PR#51776 <https://bugs.llvm.org/show_bug.cgi?id=51776>. If the object on
which `size()` is called has an overloaded `operator->`, the span for `E` will
include the `->`, and since the return type of `operator->` is a pointer,
`readability-container-size-empty` will try to add another arrow, leading to
the nonsensical `vp->->empty()` suggestion. This patch fixes this behavior.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D115124
Files:
clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
Index:
clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
===================================================================
---
clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
+++
clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
@@ -696,3 +696,17 @@
instantiatedTemplateWithSizeCall<TypeWithSize>();
instantiatedTemplateWithSizeCall<std::vector<int>>();
}
+
+namespace std {
+template <typename T>
+struct unique_ptr {
+ 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();
+}
Index: clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
@@ -194,7 +194,13 @@
if (isBinaryOrTernary(E) || isa<UnaryOperator>(E)) {
ReplacementText = "(" + ReplacementText + ")";
}
- if (E->getType()->isPointerType())
+ const auto *OpCallExpr = dyn_cast<CXXOperatorCallExpr>(E);
+ 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()";
Index: clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
@@ -696,3 +696,17 @@
instantiatedTemplateWithSizeCall<TypeWithSize>();
instantiatedTemplateWithSizeCall<std::vector<int>>();
}
+
+namespace std {
+template <typename T>
+struct unique_ptr {
+ 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();
+}
Index: clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
@@ -194,7 +194,13 @@
if (isBinaryOrTernary(E) || isa<UnaryOperator>(E)) {
ReplacementText = "(" + ReplacementText + ")";
}
- if (E->getType()->isPointerType())
+ const auto *OpCallExpr = dyn_cast<CXXOperatorCallExpr>(E);
+ 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()";
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits