Author: mitchell Date: 2025-11-09T19:12:46+03:00 New Revision: c3b31ba19c2dc1062719afcbe265aaf7d8606540
URL: https://github.com/llvm/llvm-project/commit/c3b31ba19c2dc1062719afcbe265aaf7d8606540 DIFF: https://github.com/llvm/llvm-project/commit/c3b31ba19c2dc1062719afcbe265aaf7d8606540.diff LOG: [clang-tidy] Fix `readability-container-data-pointer` check (#165636) Fix issue in readability-container-data-pointer when the container expression is a dereference (e.g., `&(*p)[0]`). The previous fix-it suggested `*p.data()`, which changes semantics because `.` binds tighter than `*`. The fix now correctly suggests `(*p).data()`. Closes [#164852](https://github.com/llvm/llvm-project/issues/164852) --------- Co-authored-by: Baranov Victor <[email protected]> Added: Modified: clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/test/clang-tidy/checkers/readability/container-data-pointer.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp index a5a6e3ce7af01..e308aefcf156a 100644 --- a/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp @@ -107,8 +107,11 @@ void ContainerDataPointerCheck::check(const MatchFinder::MatchResult &Result) { Lexer::getSourceText(CharSourceRange::getTokenRange(SrcRange), *Result.SourceManager, getLangOpts())}; - if (!isa<DeclRefExpr, ArraySubscriptExpr, CXXOperatorCallExpr, CallExpr, - MemberExpr>(CE)) + const auto *OpCall = dyn_cast<CXXOperatorCallExpr>(CE); + const bool NeedsParens = + OpCall ? (OpCall->getOperator() != OO_Subscript) + : !isa<DeclRefExpr, MemberExpr, ArraySubscriptExpr, CallExpr>(CE); + if (NeedsParens) ReplacementText = "(" + ReplacementText + ")"; if (CE->getType()->isPointerType()) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 666865cfb2fcd..48a2a1f5d39d5 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -462,6 +462,10 @@ Changes in existing checks comparisons to ``npos``. Internal changes may cause new rare false positives in non-standard containers. +- Improved :doc:`readability-container-data-pointer + <clang-tidy/checks/readability/container-data-pointer>` check by correctly + adding parentheses when the container expression is a dereference. + - Improved :doc:`readability-container-size-empty <clang-tidy/checks/readability/container-size-empty>` check by correctly generating fix-it hints when size method is called from implicit ``this``, diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/container-data-pointer.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/container-data-pointer.cpp index a8e0eb6d262e6..2ed1e939d71d4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/container-data-pointer.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/container-data-pointer.cpp @@ -35,6 +35,12 @@ template <typename T> struct enable_if<true, T> { typedef T type; }; + +template <typename T> +struct unique_ptr { + T &operator*() const; + T *operator->() const; +}; } template <typename T> @@ -144,3 +150,20 @@ int *r() { // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer] // CHECK-FIXES: return holder.v.data(); } + +void s(std::unique_ptr<std::vector<unsigned char>> p) { + f(&(*p)[0]); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer] + // CHECK-FIXES: f((*p).data()); +} + +void t(std::unique_ptr<container_without_data<unsigned char>> p) { + // p has no "data" member function, so no warning + f(&(*p)[0]); +} + +template <typename T> +void u(std::unique_ptr<T> p) { + // we don't know if 'T' will always have "data" member function, so no warning + f(&(*p)[0]); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
