[clang-tidy] Fix bugprone-string-constructor FN with allocators. (#180337)
Fixes https://github.com/llvm/llvm-project/issues/180324.
This commit is contained in:
parent
706cc8b3fe
commit
aff5afc48d
@ -81,7 +81,8 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) {
|
||||
Finder->addMatcher(
|
||||
cxxConstructExpr(
|
||||
hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
|
||||
argumentCountIs(2), hasArgument(0, hasType(qualType(isInteger()))),
|
||||
anyOf(argumentCountIs(2), argumentCountIs(3)),
|
||||
hasArgument(0, hasType(qualType(isInteger()))),
|
||||
hasArgument(1, hasType(qualType(isInteger()))),
|
||||
anyOf(
|
||||
// Detect the expression: string('x', 40);
|
||||
@ -101,7 +102,10 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) {
|
||||
cxxConstructExpr(
|
||||
hasDeclaration(cxxConstructorDecl(ofClass(
|
||||
cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)))))),
|
||||
argumentCountIs(2), hasArgument(0, hasType(CharPtrType)),
|
||||
anyOf(argumentCountIs(2),
|
||||
allOf(argumentCountIs(3),
|
||||
hasArgument(2, unless(hasType(qualType(isInteger())))))),
|
||||
hasArgument(0, hasType(CharPtrType)),
|
||||
hasArgument(1, hasType(isInteger())),
|
||||
anyOf(
|
||||
// Detect the expression: string("...", 0);
|
||||
@ -123,7 +127,8 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) {
|
||||
cxxConstructExpr(
|
||||
hasDeclaration(cxxConstructorDecl(ofClass(
|
||||
cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)))))),
|
||||
argumentCountIs(3), hasArgument(0, hasType(CharPtrType)),
|
||||
anyOf(argumentCountIs(3), argumentCountIs(4)),
|
||||
hasArgument(0, hasType(CharPtrType)),
|
||||
hasArgument(1, hasType(qualType(isInteger()))),
|
||||
hasArgument(2, hasType(qualType(isInteger()))),
|
||||
anyOf(
|
||||
|
||||
@ -148,6 +148,11 @@ Changes in existing checks
|
||||
<clang-tidy/checks/bugprone/macro-parentheses>` check by printing the macro
|
||||
definition in the warning message if the macro is defined on command line.
|
||||
|
||||
- Improved :doc:`bugprone-string-constructor
|
||||
<clang-tidy/checks/bugprone/string-constructor>` check to detect suspicious
|
||||
string constructor calls when the string class constructor has a default
|
||||
allocator argument.
|
||||
|
||||
- Improved :doc:`bugprone-unsafe-functions
|
||||
<clang-tidy/checks/bugprone/unsafe-functions>` check by adding the function
|
||||
``std::get_temporary_buffer`` to the default list of unsafe functions. (This
|
||||
|
||||
@ -8,10 +8,10 @@ class char_traits {};
|
||||
template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C> >
|
||||
struct basic_string {
|
||||
basic_string();
|
||||
basic_string(const C*, unsigned int size);
|
||||
basic_string(const C*, unsigned int size, const A &a = A());
|
||||
basic_string(const C *, const A &allocator = A());
|
||||
basic_string(unsigned int size, C c);
|
||||
basic_string(const C*, unsigned int pos, unsigned int size);
|
||||
basic_string(unsigned int size, C c, const A &a = A());
|
||||
basic_string(const C*, unsigned int pos, unsigned int size, const A &a = A());
|
||||
};
|
||||
typedef basic_string<char> string;
|
||||
typedef basic_string<wchar_t> wstring;
|
||||
@ -119,6 +119,44 @@ std::string_view StringViewFromZero() {
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour
|
||||
}
|
||||
|
||||
void TestExplicitAllocator() {
|
||||
std::allocator<char> a;
|
||||
|
||||
std::string s1('x', 5, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: string constructor parameters are probably swapped; expecting string(count, character) [bugprone-string-constructor]
|
||||
// CHECK-FIXES: std::string s1(5, 'x', a);
|
||||
std::string s2(0, 'x', a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
|
||||
std::string s3(-4, 'x', a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter
|
||||
std::string s4(0x1000000, 'x', a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
|
||||
|
||||
std::string q0("test", 0, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
|
||||
std::string q1(kText, -4, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter
|
||||
std::string q2("test", 200, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
|
||||
std::string q3(kText3, 0x1000000, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
|
||||
|
||||
std::string r1("test", 1, 0, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
|
||||
std::string r2("test", 0, -4, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter
|
||||
std::string r3("test", -4, 1, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as position of the first character parameter
|
||||
std::string r4("test", 0, 0x1000000, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
|
||||
std::string r5("test", 0, 5, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
|
||||
std::string r6("test", 3, 2, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than remaining string literal size
|
||||
std::string r7("test", 4, 1, a);
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: position of the first character parameter is bigger than string literal character range
|
||||
}
|
||||
|
||||
void Valid() {
|
||||
std::string empty();
|
||||
std::string str(4, 'x');
|
||||
@ -132,6 +170,13 @@ void Valid() {
|
||||
std::string s8("test", 3, 1);
|
||||
std::string s9("te" "st", 1, 2);
|
||||
|
||||
std::allocator<char> a;
|
||||
std::string sa1(4, 'x', a);
|
||||
std::string sa2("test", 4, a);
|
||||
std::string sa3("test", 3, a);
|
||||
std::string sa4("test", 0, 4, a);
|
||||
std::string sa5("test", 3, 1, a);
|
||||
|
||||
std::string_view emptyv();
|
||||
std::string_view sv1("test", 4);
|
||||
std::string_view sv2("test", 3);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user