[PATCH] D140968: [clang-tidy] Add check for passing the result of `std::string::c_str` to `strlen`

2023-01-09 Thread Alex Coster via Phabricator via cfe-commits
acoster added a comment.

In D140968#4029072 , @njames93 wrote:

> I don't see the appear of this check as its a situation that I doubt ever 
> appears in code bases. If there are open source code bases where this is a 
> known problem can you please provide links to them as well as running the 
> run_clang_tidy script over them to verify the changes are good.

After a look at some projects, it seems like the pattern does arise, but often 
it's intended (eg a string buffer is set to a large size, a legacy function 
taking a char* writes to it, and then the string is resized to 
strlen(foo.c_str())). As such, I'll drop this patch, as it can introduce bugs 
in these cases.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140968/new/

https://reviews.llvm.org/D140968

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140968: [clang-tidy] Add check for passing the result of `std::string::c_str` to `strlen`

2023-01-05 Thread Nathan James via Phabricator via cfe-commits
njames93 requested changes to this revision.
njames93 added a comment.
This revision now requires changes to proceed.

I don't see the appear of this check as its a situation that I doubt ever 
appears in code bases. If there are open source code bases where this is a 
known problem can you please provide links to them as well as running the 
run_clang_tidy script over them to verify the changes are good.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140968/new/

https://reviews.llvm.org/D140968

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140968: [clang-tidy] Add check for passing the result of `std::string::c_str` to `strlen`

2023-01-05 Thread Alex Coster via Phabricator via cfe-commits
acoster updated this revision to Diff 486582.
acoster added a comment.

Fix length of comment at the top of StrlenStringCStrCheck.h


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140968/new/

https://reviews.llvm.org/D140968

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.cpp
  clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst
  clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp
@@ -0,0 +1,117 @@
+// RUN: %check_clang_tidy %s readability-strlen-string-cstr %t
+int strlen(const char *);
+int strnlen(const char *, int);
+int strnlen_s(const char *, int);
+
+int wcslen(const wchar_t *);
+int wcsnlen_s(const wchar_t *, int);
+
+namespace std {
+template  class allocator {};
+template  class char_traits {};
+
+template >
+class basic_string_view {
+public:
+  basic_string_view();
+  basic_string_view(const basic_string_view &other);
+  const C *data() const;
+  int size() const;
+  int length() const;
+};
+
+using string_view = basic_string_view;
+using wstring_view = basic_string_view;
+
+template ,
+  typename A = std::allocator>
+class basic_string {
+public:
+  basic_string();
+  basic_string(const C *, unsigned int size);
+  basic_string(const C *, const A &allocator = A());
+  const C *c_str() const;
+  const C *data() const;
+  int size() const;
+  int length() const;
+  operator basic_string_view() const;
+};
+
+using wstring = basic_string;
+using string = basic_string;
+
+int strlen(const char *);
+int wcslen(const wchar_t *);
+} // namespace std
+
+void handlesBasicString() {
+  std::string str1("a", 1);
+  int length = strlen(str1.c_str());
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant call to 'strlen' {{.*}}
+  // CHECK-FIXES: {{^  }}int length = str1.size();{{$}}
+
+  length = strnlen(str1.data(), 30);
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant call to 'strnlen' {{.*}}
+  // CHECK-FIXES: {{^  }}length = str1.size();{{$}}
+
+  const std::string *p1 = &str1;
+  length = std::strlen(p1->c_str()) + 30;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant call {{.*}}
+  // CHECK-FIXES: {{^  }}length = p1->size() + 30;{{$}}
+
+  std::wstring wstr1;
+  length = wcslen(wstr1.c_str());
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant call to 'wcslen' {{.*}}
+  // CHECK-FIXES: {{^  }}length = wstr1.size();{{$}}
+
+  const std::wstring &wstr2 = wstr1;
+  length = std::wcslen(wstr2.data());
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant call to {{.*}}
+  // CHECK-FIXES: {{^  }}length = wstr2.size();{{$}}
+}
+
+void handlesStringView() {
+  std::string str1("foo");
+  std::string_view view = str1;
+  int length = strnlen_s(view.data(), 300);
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant call to 'strnlen_s'
+  // {{.*}} CHECK-FIXES: {{^  }}int length = view.size();{{$}}
+
+  std::wstring wstr1;
+  std::wstring_view wview = wstr1;
+  length = wcsnlen_s(wview.data(), 300);
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant call to 'wcsnlen_s'
+  // {{.*}} CHECK-FIXES: {{^  }}length = wview.size();{{$}}
+}
+
+class CustomStringClass {
+public:
+  CustomStringClass(int, char);
+  const char *data() const;
+  int length() const;
+
+private:
+  int size() const;
+};
+
+void handlesStringLikeTypes() {
+  CustomStringClass str(123, 'f');
+  int size = strlen(str.data());
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: redundant call to
+  // CHECK-FIXES: {{^  }}int size = str.length();{{$}}
+}
+
+class StringWithoutPublicSizeMethod {
+public:
+  StringWithoutPublicSizeMethod(const char *);
+  const char *c_str();
+
+private:
+  int size() const;
+  int length() const;
+};
+
+void ignoresStringTypesWithoutPublicSizeMethod() {
+  StringWithoutPublicSizeMethod str("foo");
+  int length = strlen(str.c_str());
+}
Index: clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst
@@ -0,0 +1,22 @@
+.. title:: clang-tidy - readability-strlen-string-cstr
+
+readability-strlen-string-cstr
+==
+
+Warns when the return value of ``c_str()`` or ``data()`` is used as an argument
+for ``strlen``, and suggests using ``size()``or ``length()`` if one of them is
+a member function.
+
+Example
+---
+
+.. code-blo

[PATCH] D140968: [clang-tidy] Add check for passing the result of `std::string::c_str` to `strlen`

2023-01-05 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.h:1
+//===--- StrlenStringCStrCheck.h - clang-tidy *- C++ -*-===//
+//

Should be 80 characters long. See other checks as example.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140968/new/

https://reviews.llvm.org/D140968

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140968: [clang-tidy] Add check for passing the result of `std::string::c_str` to `strlen`

2023-01-05 Thread Alex Coster via Phabricator via cfe-commits
acoster marked 12 inline comments as done.
acoster added inline comments.



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst:24
+
+.. option:: EnableForDataMethod
+

carlosgalvezp wrote:
> Is there a use case for wanting this option? (As opposed to unconditionally 
> warning about data()) The problem is the same and the same fix applies?
@carlosgalvezp Removed the option.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140968/new/

https://reviews.llvm.org/D140968

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140968: [clang-tidy] Add check for passing the result of `std::string::c_str` to `strlen`

2023-01-05 Thread Alex Coster via Phabricator via cfe-commits
acoster updated this revision to Diff 486504.
acoster added a comment.

Generlised the check to cover string_view and "string-like" classes

Removed the option of ignoring `data()`, and generalised the check to suggest
fixes if the result of `data()` or `c_str()` method of any class with a public
`length()` or `size()` method is passed to `strlen`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140968/new/

https://reviews.llvm.org/D140968

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.cpp
  clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst
  clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp
@@ -0,0 +1,117 @@
+// RUN: %check_clang_tidy %s readability-strlen-string-cstr %t
+int strlen(const char *);
+int strnlen(const char *, int);
+int strnlen_s(const char *, int);
+
+int wcslen(const wchar_t *);
+int wcsnlen_s(const wchar_t *, int);
+
+namespace std {
+template  class allocator {};
+template  class char_traits {};
+
+template >
+class basic_string_view {
+public:
+  basic_string_view();
+  basic_string_view(const basic_string_view &other);
+  const C *data() const;
+  int size() const;
+  int length() const;
+};
+
+using string_view = basic_string_view;
+using wstring_view = basic_string_view;
+
+template ,
+  typename A = std::allocator>
+class basic_string {
+public:
+  basic_string();
+  basic_string(const C *, unsigned int size);
+  basic_string(const C *, const A &allocator = A());
+  const C *c_str() const;
+  const C *data() const;
+  int size() const;
+  int length() const;
+  operator basic_string_view() const;
+};
+
+using wstring = basic_string;
+using string = basic_string;
+
+int strlen(const char *);
+int wcslen(const wchar_t *);
+} // namespace std
+
+void handlesBasicString() {
+  std::string str1("a", 1);
+  int length = strlen(str1.c_str());
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant call to 'strlen' {{.*}}
+  // CHECK-FIXES: {{^  }}int length = str1.size();{{$}}
+
+  length = strnlen(str1.data(), 30);
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant call to 'strnlen' {{.*}}
+  // CHECK-FIXES: {{^  }}length = str1.size();{{$}}
+
+  const std::string *p1 = &str1;
+  length = std::strlen(p1->c_str()) + 30;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant call {{.*}}
+  // CHECK-FIXES: {{^  }}length = p1->size() + 30;{{$}}
+
+  std::wstring wstr1;
+  length = wcslen(wstr1.c_str());
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant call to 'wcslen' {{.*}}
+  // CHECK-FIXES: {{^  }}length = wstr1.size();{{$}}
+
+  const std::wstring &wstr2 = wstr1;
+  length = std::wcslen(wstr2.data());
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant call to {{.*}}
+  // CHECK-FIXES: {{^  }}length = wstr2.size();{{$}}
+}
+
+void handlesStringView() {
+  std::string str1("foo");
+  std::string_view view = str1;
+  int length = strnlen_s(view.data(), 300);
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant call to 'strnlen_s'
+  // {{.*}} CHECK-FIXES: {{^  }}int length = view.size();{{$}}
+
+  std::wstring wstr1;
+  std::wstring_view wview = wstr1;
+  length = wcsnlen_s(wview.data(), 300);
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant call to 'wcsnlen_s'
+  // {{.*}} CHECK-FIXES: {{^  }}length = wview.size();{{$}}
+}
+
+class CustomStringClass {
+public:
+  CustomStringClass(int, char);
+  const char *data() const;
+  int length() const;
+
+private:
+  int size() const;
+};
+
+void handlesStringLikeTypes() {
+  CustomStringClass str(123, 'f');
+  int size = strlen(str.data());
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: redundant call to
+  // CHECK-FIXES: {{^  }}int size = str.length();{{$}}
+}
+
+class StringWithoutPublicSizeMethod {
+public:
+  StringWithoutPublicSizeMethod(const char *);
+  const char *c_str();
+
+private:
+  int size() const;
+  int length() const;
+};
+
+void ignoresStringTypesWithoutPublicSizeMethod() {
+  StringWithoutPublicSizeMethod str("foo");
+  int length = strlen(str.c_str());
+}
Index: clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst
@@ -0,0 +1,22 @@
+.. title:: clang-tidy - readability-strlen-string-cstr
+
+readability-strlen-string-cstr
+=

[PATCH] D140968: [clang-tidy] Add check for passing the result of `std::string::c_str` to `strlen`

2023-01-04 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp added inline comments.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp:1
+// RUN: %check_clang_tidy -check-suffix=0 %s readability-strlen-string-cstr %t 
 -- -config="{CheckOptions: [{key: 
readability-strlen-string-cstr.EnableForDataMethod, value: false}]}"
+// RUN: %check_clang_tidy -check-suffix=1 %s readability-strlen-string-cstr %t 
 -- -config="{CheckOptions: [{key: 
readability-strlen-string-cstr.EnableForDataMethod, value: true}]}"

The default case typically doesn't need a suffix.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp:2
+// RUN: %check_clang_tidy -check-suffix=0 %s readability-strlen-string-cstr %t 
 -- -config="{CheckOptions: [{key: 
readability-strlen-string-cstr.EnableForDataMethod, value: false}]}"
+// RUN: %check_clang_tidy -check-suffix=1 %s readability-strlen-string-cstr %t 
 -- -config="{CheckOptions: [{key: 
readability-strlen-string-cstr.EnableForDataMethod, value: true}]}"
+int strlen(const char *);

Please give a more descriptive name



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp:35
+  int length = strlen(str1.c_str());
+  // CHECK-MESSAGES-0: [[@LINE-1]]:16: warning: redundant call to 'strlen' 
{{.*}}
+  // CHECK-FIXES-0: {{^  }}int length = str1.size();{{$}}

Tip: you don't need to write duplicate checks, you can simply skip the suffix 
and it will apply to both RUN lines:

// CHECK-MESSAGES:  ...
// CHECK-FIXES: ...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140968/new/

https://reviews.llvm.org/D140968

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140968: [clang-tidy] Add check for passing the result of `std::string::c_str` to `strlen`

2023-01-04 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp added inline comments.



Comment at: clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.h:23
+  : ClangTidyCheck(Name, Context),
+EnableForDataMethod(Options.get("EnableForDataMethod", false)) {}
+

The docs say this is "true" by default, but here you are setting it to false.



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst:24
+
+.. option:: EnableForDataMethod
+

Is there a use case for wanting this option? (As opposed to unconditionally 
warning about data()) The problem is the same and the same fix applies?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140968/new/

https://reviews.llvm.org/D140968

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140968: [clang-tidy] Add check for passing the result of `std::string::c_str` to `strlen`

2023-01-04 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.cpp:1
+//===- StrlenStringCStrCheck.cpp - Check for strlen(string::c_str()) calls
+//-===//

Please make it single string.



Comment at: 
clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.cpp:35
+  cxxMethodDecl(MethodNameMatcher,
+ofClass(cxxRecordDecl(hasName("::std::basic_string"));
+  const auto StrlenCall =

What about `std::basic_string_view`? Or any class with `c_str/data/length/size`?



Comment at: 
clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.cpp:66
+} // namespace clang
\ No newline at end of file


Please fix.



Comment at: clang-tools-extra/docs/ReleaseNotes.rst:135
+
+Warns when the return value of `std::basic_string::c_str` or 
`std::basic_string::data`
+is used as the argument for `strlen`, and suggests a fix.

Please use double back-ticks for language constructs.



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst:6
+
+Finds calls to ``strlen`` and similar functions where the result
+of ``std::basic_string::c_str`` or ``std::basic_string::data`` is used

Please make it same as statement in Release Notes.



Comment at: 
clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst:30
+``std::basic_string::data`` is used as an argument for ``strlen``.
\ No newline at end of file


Please fix.



Comment at: 
clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp:61
+}
\ No newline at end of file


Please fix.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140968/new/

https://reviews.llvm.org/D140968

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D140968: [clang-tidy] Add check for passing the result of `std::string::c_str` to `strlen`

2023-01-04 Thread Alex Coster via Phabricator via cfe-commits
acoster created this revision.
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a reviewer: njames93.
Herald added a project: All.
acoster requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Suggests replacing the call with `std::string::size`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140968

Files:
  clang-tools-extra/clang-tidy/readability/CMakeLists.txt
  clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.cpp
  clang-tools-extra/clang-tidy/readability/StrlenStringCStrCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst
  clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/readability/strlen-string-cstr.cpp
@@ -0,0 +1,60 @@
+// RUN: %check_clang_tidy -check-suffix=0 %s readability-strlen-string-cstr %t  -- -config="{CheckOptions: [{key: readability-strlen-string-cstr.EnableForDataMethod, value: false}]}"
+// RUN: %check_clang_tidy -check-suffix=1 %s readability-strlen-string-cstr %t  -- -config="{CheckOptions: [{key: readability-strlen-string-cstr.EnableForDataMethod, value: true}]}"
+int strlen(const char *);
+int strnlen(const char *, int);
+int strnlen_s(const char *, int);
+
+int wcslen(const wchar_t *);
+int wcsnlen_s(const wchar_t *, int);
+
+namespace std {
+template  class allocator {};
+template  class char_traits {};
+
+template ,
+  typename A = std::allocator>
+class basic_string {
+public:
+  basic_string();
+  basic_string(const C *, unsigned int size);
+  const C *c_str() const;
+  const C *data() const;
+  int size() const;
+};
+
+using wstring = basic_string;
+using string = basic_string;
+
+int strlen(const char *);
+int wcslen(const wchar_t *);
+} // namespace std
+
+void f1() {
+  std::string str1("a", 1);
+  int length = strlen(str1.c_str());
+  // CHECK-MESSAGES-0: [[@LINE-1]]:16: warning: redundant call to 'strlen' {{.*}}
+  // CHECK-FIXES-0: {{^  }}int length = str1.size();{{$}}
+  // CHECK-MESSAGES-1: [[@LINE-3]]:16: warning: redundant call to 'strlen' {{.*}}
+  // CHECK-FIXES-1: {{^  }}int length = str1.size();{{$}}
+
+  length = strnlen(str1.data(), 30);
+  // CHECK-MESSAGES-1: [[@LINE-1]]:12: warning: redundant call to 'strnlen' {{.*}}
+  // CHECK-FIXES-1: {{^  }}length = str1.size();{{$}}
+
+  const std::string *p1 = &str1;
+  length = std::strlen(p1->c_str()) + 30;
+  // CHECK-MESSAGES-0: [[@LINE-1]]:12: warning: redundant call {{.*}}
+  // CHECK-FIXES-0: {{^  }}length = p1->size() + 30;{{$}}
+  // CHECK-MESSAGES-1: [[@LINE-3]]:12: warning: redundant call {{.*}}
+  // CHECK-FIXES-1: {{^  }}length = p1->size() + 30;{{$}}
+}
+
+void f2() {
+  std::wstring wstr1;
+
+  int length = wcslen(wstr1.c_str());
+  // CHECK-MESSAGES-0: [[@LINE-1]]:16: warning: redundant call to 'wcslen' {{.*}}
+  // CHECK-FIXES-0: {{^  }}int length = wstr1.size();{{$}}
+  // CHECK-MESSAGES-1: [[@LINE-3]]:16: warning: redundant call to 'wcslen' {{.*}}
+  // CHECK-FIXES-1: {{^  }}int length = wstr1.size();{{$}}
+}
\ No newline at end of file
Index: clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/readability/strlen-string-cstr.rst
@@ -0,0 +1,29 @@
+.. title:: clang-tidy - readability-strlen-string-cstr
+
+readability-strlen-string-cstr
+==
+
+Finds calls to ``strlen`` and similar functions where the result
+of ``std::basic_string::c_str`` or ``std::basic_string::data`` is used
+as an argument. 
+
+Example
+---
+
+.. code-block:: c++
+
+std::string str1{"foo"}
+
+// Use str1.size()
+size_t length = strlen(str1.c_str());
+
+
+Options
+---
+
+.. option:: EnableForDataMethod
+
+Default is `true`.
+
+When `false`, the check will not warn then the result of 
+``std::basic_string::data`` is used as an argument for ``strlen``.
\ No newline at end of file
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -362,6 +362,7 @@
`readability-static-accessed-through-instance `_, "Yes"
`readability-static-definition-in-anonymous-namespace `_, "Yes"
`readability-string-compare `_, "Yes"
+   `readability-strlen-string-cstr `_, "Yes"
`readability-suspicious-call-argument `_,
`readability-uniqueptr-delete-release `_, "Yes"
`readability-uppercase-literal-suf