-
Notifications
You must be signed in to change notification settings - Fork 15k
[clang-tidy] Fix readability-container-data-pointer check
#165636
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-clang-tools-extra Author: mitchell (zeyi2) ChangesFix issue in readability-container-data-pointer when the container expression is a dereference (e.g., Closes #164852 Full diff: https://github.com/llvm/llvm-project/pull/165636.diff 2 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp
index 11756d10a8221..d9338888cc40e 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);
+ 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/test/clang-tidy/checkers/readability/container-data-pointer.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/container-data-pointer.cpp
index a8e0eb6d262e6..26f9d9f16ac8c 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,9 @@ 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());
+}
|
|
@llvm/pr-subscribers-clang-tidy Author: mitchell (zeyi2) ChangesFix issue in readability-container-data-pointer when the container expression is a dereference (e.g., Closes #164852 Full diff: https://github.com/llvm/llvm-project/pull/165636.diff 2 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp
index 11756d10a8221..d9338888cc40e 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);
+ 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/test/clang-tidy/checkers/readability/container-data-pointer.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/container-data-pointer.cpp
index a8e0eb6d262e6..26f9d9f16ac8c 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,9 @@ 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());
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please mention changes in Release Notes.
| if (!isa<DeclRefExpr, ArraySubscriptExpr, CXXOperatorCallExpr, CallExpr, | ||
| MemberExpr>(CE)) | ||
| const auto *OpCall = dyn_cast<CXXOperatorCallExpr>(CE); | ||
| bool NeedsParens = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| bool NeedsParens = | |
| const bool NeedsParens = |
| // CHECK-FIXES: return holder.v.data(); | ||
| } | ||
|
|
||
| void s(std::unique_ptr<std::vector<unsigned char>> p) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add test with templated function and unique_ptr<T>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, thanks for reviewing. I've added a new test as requested :)
| SourceRange SrcRange = CE->getSourceRange(); | ||
| const Expr *PrintedCE = CE->IgnoreParenImpCasts(); | ||
|
|
||
| SourceRange SrcRange = PrintedCE->getSourceRange(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| SourceRange SrcRange = PrintedCE->getSourceRange(); | |
| const SourceRange SrcRange = PrintedCE->getSourceRange(); |
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