Skip to content

Commit c3b31ba

Browse files
zeyi2vbvictor
andauthored
[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](#164852) --------- Co-authored-by: Baranov Victor <[email protected]>
1 parent 2095ea5 commit c3b31ba

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,11 @@ void ContainerDataPointerCheck::check(const MatchFinder::MatchResult &Result) {
107107
Lexer::getSourceText(CharSourceRange::getTokenRange(SrcRange),
108108
*Result.SourceManager, getLangOpts())};
109109

110-
if (!isa<DeclRefExpr, ArraySubscriptExpr, CXXOperatorCallExpr, CallExpr,
111-
MemberExpr>(CE))
110+
const auto *OpCall = dyn_cast<CXXOperatorCallExpr>(CE);
111+
const bool NeedsParens =
112+
OpCall ? (OpCall->getOperator() != OO_Subscript)
113+
: !isa<DeclRefExpr, MemberExpr, ArraySubscriptExpr, CallExpr>(CE);
114+
if (NeedsParens)
112115
ReplacementText = "(" + ReplacementText + ")";
113116

114117
if (CE->getType()->isPointerType())

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,10 @@ Changes in existing checks
462462
comparisons to ``npos``. Internal changes may cause new rare false positives
463463
in non-standard containers.
464464

465+
- Improved :doc:`readability-container-data-pointer
466+
<clang-tidy/checks/readability/container-data-pointer>` check by correctly
467+
adding parentheses when the container expression is a dereference.
468+
465469
- Improved :doc:`readability-container-size-empty
466470
<clang-tidy/checks/readability/container-size-empty>` check by correctly
467471
generating fix-it hints when size method is called from implicit ``this``,

clang-tools-extra/test/clang-tidy/checkers/readability/container-data-pointer.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ template <typename T>
3535
struct enable_if<true, T> {
3636
typedef T type;
3737
};
38+
39+
template <typename T>
40+
struct unique_ptr {
41+
T &operator*() const;
42+
T *operator->() const;
43+
};
3844
}
3945

4046
template <typename T>
@@ -144,3 +150,20 @@ int *r() {
144150
// 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]
145151
// CHECK-FIXES: return holder.v.data();
146152
}
153+
154+
void s(std::unique_ptr<std::vector<unsigned char>> p) {
155+
f(&(*p)[0]);
156+
// 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]
157+
// CHECK-FIXES: f((*p).data());
158+
}
159+
160+
void t(std::unique_ptr<container_without_data<unsigned char>> p) {
161+
// p has no "data" member function, so no warning
162+
f(&(*p)[0]);
163+
}
164+
165+
template <typename T>
166+
void u(std::unique_ptr<T> p) {
167+
// we don't know if 'T' will always have "data" member function, so no warning
168+
f(&(*p)[0]);
169+
}

0 commit comments

Comments
 (0)