Author: courbet Date: Wed Jan 16 00:36:23 2019 New Revision: 351308 URL: http://llvm.org/viewvc/llvm-project?rev=351308&view=rev Log: [clang-tidy] bugprone-string-constructor: Catch string from nullptr.
Summary: Context: https://twitter.com/willkirkby/status/1084219580799741953 Subscribers: xazax.hun, cfe-commits Differential Revision: https://reviews.llvm.org/D56657 Modified: clang-tools-extra/trunk/clang-tidy/bugprone/StringConstructorCheck.cpp clang-tools-extra/trunk/test/clang-tidy/bugprone-string-constructor.cpp Modified: clang-tools-extra/trunk/clang-tidy/bugprone/StringConstructorCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/StringConstructorCheck.cpp?rev=351308&r1=351307&r2=351308&view=diff ============================================================================== --- clang-tools-extra/trunk/clang-tidy/bugprone/StringConstructorCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/bugprone/StringConstructorCheck.cpp Wed Jan 16 00:36:23 2019 @@ -100,6 +100,15 @@ void StringConstructorCheck::registerMat integerLiteral().bind("int")))))) .bind("constructor"), this); + + // Check the literal string constructor with char pointer. + // [i.e. string (const char* s);] + Finder->addMatcher( + cxxConstructExpr(hasDeclaration(cxxMethodDecl(hasName("basic_string"))), + hasArgument(0, expr().bind("from-ptr")), + hasArgument(1, unless(hasType(isInteger())))) + .bind("constructor"), + this); } void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { @@ -128,6 +137,13 @@ void StringConstructorCheck::check(const if (Lit->getValue().ugt(Str->getLength())) { diag(Loc, "length is bigger then string literal size"); } + } else if (const auto *Ptr = Result.Nodes.getNodeAs<Expr>("from-ptr")) { + Expr::EvalResult ConstPtr; + if (Ptr->EvaluateAsRValue(ConstPtr, Ctx) && + ((ConstPtr.Val.isInt() && ConstPtr.Val.getInt().isNullValue()) || + (ConstPtr.Val.isLValue() && ConstPtr.Val.isNullPointer()))) { + diag(Loc, "constructing string from nullptr is undefined behaviour"); + } } } Modified: clang-tools-extra/trunk/test/clang-tidy/bugprone-string-constructor.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/bugprone-string-constructor.cpp?rev=351308&r1=351307&r2=351308&view=diff ============================================================================== --- clang-tools-extra/trunk/test/clang-tidy/bugprone-string-constructor.cpp (original) +++ clang-tools-extra/trunk/test/clang-tidy/bugprone-string-constructor.cpp Wed Jan 16 00:36:23 2019 @@ -9,6 +9,7 @@ template <typename C, typename T = std:: struct basic_string { basic_string(); basic_string(const C*, unsigned int size); + basic_string(const C *, const A &allocator = A()); basic_string(unsigned int size, C c); }; typedef basic_string<char> string; @@ -45,6 +46,15 @@ void Test() { // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger then string literal size std::string q5(kText3, 0x1000000); // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter + std::string q6(nullptr); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructing string from nullptr is undefined behaviour + std::string q7 = 0; + // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour +} + +std::string StringFromZero() { + return 0; + // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour } void Valid() { @@ -53,4 +63,5 @@ void Valid() { std::wstring wstr(4, L'x'); std::string s1("test", 4); std::string s2("test", 3); + std::string s3("test"); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits