diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -121,17 +121,20 @@ // Check the literal string constructor with char pointer. // [i.e. string (const char* s);] Finder->addMatcher( - traverse(TK_AsIs, - cxxConstructExpr( - hasDeclaration(cxxConstructorDecl(ofClass(cxxRecordDecl( - hasAnyName(removeNamespaces(StringNames)))))), - hasArgument(0, expr().bind("from-ptr")), - // do not match std::string(ptr, int) - // match std::string(ptr, alloc) - // match std::string(ptr) - anyOf(hasArgument(1, unless(hasType(isInteger()))), - argumentCountIs(1))) - .bind("constructor")), + traverse( + TK_AsIs, + cxxConstructExpr( + hasDeclaration(cxxConstructorDecl(ofClass(anyOf( + cxxRecordDecl(hasName("basic_string_view")) + .bind("basic_string_view_decl"), + cxxRecordDecl(hasAnyName(removeNamespaces(StringNames))))))), + hasArgument(0, expr().bind("from-ptr")), + // do not match std::string(ptr, int) + // match std::string(ptr, alloc) + // match std::string(ptr) + anyOf(hasArgument(1, unless(hasType(isInteger()))), + argumentCountIs(1))) + .bind("constructor")), this); } @@ -167,6 +170,11 @@ Ptr->EvaluateAsRValue(ConstPtr, Ctx) && ((ConstPtr.Val.isInt() && ConstPtr.Val.getInt().isZero()) || (ConstPtr.Val.isLValue() && ConstPtr.Val.isNullPointer()))) { + if (Result.Nodes.getNodeAs("basic_string_view_decl")) { + // Filter out basic_string_view to avoid conflicts with + // bugprone-stringview-nullptr + return; + } diag(Loc, "constructing string from nullptr is undefined behaviour"); } } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-string-constructor.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-string-constructor.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-string-constructor.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-string-constructor.cpp @@ -74,10 +74,6 @@ // CHECK-MESSAGES: [[@LINE-1]]:20: warning: length is bigger than string literal size std::string_view q5(kText3, 0x1000000); // CHECK-MESSAGES: [[@LINE-1]]:20: warning: suspicious large length parameter - std::string_view q6(nullptr); - // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour - std::string_view q7 = 0; - // CHECK-MESSAGES: [[@LINE-1]]:25: warning: constructing string from nullptr is undefined behaviour } std::string StringFromZero() { @@ -85,11 +81,6 @@ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour } -std::string_view StringViewFromZero() { - return 0; - // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour -} - void Valid() { std::string empty(); std::string str(4, 'x');