// be present explicitly.
hasArgument(1, cxxDefaultArgExpr()))));
+ // Match string constructor.
+ const auto StringViewConstructorExpr = cxxConstructExpr(
+ argumentCountIs(1),
+ hasDeclaration(cxxMethodDecl(hasName("basic_string_view"))));
+
// Match a call to the string 'c_str()' method.
const auto StringCStrCallExpr =
cxxMemberCallExpr(on(StringExpr.bind("arg")),
traverse(
TK_AsIs,
cxxConstructExpr(
- StringConstructorExpr, hasArgument(0, StringCStrCallExpr),
+ anyOf(StringConstructorExpr, StringViewConstructorExpr),
+ hasArgument(0, StringCStrCallExpr),
unless(anyOf(HasRValueTempParent, hasParent(cxxBindTemporaryExpr(
HasRValueTempParent)))))),
this);
typedef basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>> wstring;
typedef basic_string<char16, std::char_traits<char16>, std::allocator<char16>> u16string;
typedef basic_string<char32, std::char_traits<char32>, std::allocator<char32>> u32string;
+
+template <typename C, typename T>
+struct basic_string_view {
+ basic_string_view(const C* s);
+};
+typedef basic_string_view<char, std::char_traits<char>> string_view;
+typedef basic_string_view<wchar_t, std::char_traits<wchar_t>> wstring_view;
+typedef basic_string_view<char16, std::char_traits<char16>> u16string_view;
+typedef basic_string_view<char32, std::char_traits<char32>> u32string_view;
}
std::string operator+(const std::string&, const std::string&);
tmp.insert(1, s);
tmp.insert(1, s.c_str(), 2);
}
+void f7(std::string_view sv) {
+ std::string s;
+ f7(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}f7(s);{{$}}
+ f7(s.data());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'data' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}f7(s);{{$}}
+}
// Tests for std::wstring.
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
// CHECK-FIXES: {{^ }}g1(s);{{$}}
}
+void g2(std::wstring_view sv) {
+ std::wstring s;
+ g2(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}g2(s);{{$}}
+ g2(s.data());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'data' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}g2(s);{{$}}
+}
// Tests for std::u16string.
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
// CHECK-FIXES: {{^ }}h1(s);{{$}}
}
+void h2(std::u16string_view sv) {
+ std::u16string s;
+ h2(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}h2(s);{{$}}
+ h2(s.data());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'data' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}h2(s);{{$}}
+}
// Tests for std::u32string.
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
// CHECK-FIXES: {{^ }}k1(s);{{$}}
}
+void k2(std::u32string_view sv) {
+ std::u32string s;
+ k2(s.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}k2(s);{{$}}
+ k2(s.data());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to 'data' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}k2(s);{{$}}
+}
// Tests on similar classes that aren't good candidates for this checker.