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

Reply via email to