Index: clang-tidy/google/CMakeLists.txt =================================================================== --- clang-tidy/google/CMakeLists.txt +++ clang-tidy/google/CMakeLists.txt @@ -5,6 +5,7 @@ ExplicitConstructorCheck.cpp ExplicitMakePairCheck.cpp GoogleTidyModule.cpp + MemberStringReferencesCheck.cpp NamedParameterCheck.cpp OverloadedUnaryAndCheck.cpp Index: clang-tidy/google/GoogleTidyModule.cpp =================================================================== --- clang-tidy/google/GoogleTidyModule.cpp +++ clang-tidy/google/GoogleTidyModule.cpp @@ -13,6 +13,7 @@ #include "AvoidCStyleCastsCheck.h" #include "ExplicitConstructorCheck.h" #include "ExplicitMakePairCheck.h" +#include "MemberStringReferencesCheck.h" #include "NamedParameterCheck.h" #include "OverloadedUnaryAndCheck.h" @@ -31,6 +32,9 @@ "google-explicit-constructor", new ClangTidyCheckFactory()); CheckFactories.addCheckFactory( + "google-runtime-member-string-references", + new ClangTidyCheckFactory()); + CheckFactories.addCheckFactory( "google-runtime-operator", new ClangTidyCheckFactory()); CheckFactories.addCheckFactory( Index: clang-tidy/google/MemberStringReferencesCheck.h =================================================================== --- /dev/null +++ clang-tidy/google/MemberStringReferencesCheck.h @@ -0,0 +1,36 @@ +//===--- MemberStringReferenceCheck.h - clang-tidy ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_MEMBER_STRING_REF_CHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_MEMBER_STRING_REF_CHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace runtime { + +/// \brief Finds members of type 'const string&'. +/// +/// const string reference members are generally considered unsafe. This check +/// emit warnings for both std::string and ::string const reference members. +/// +/// http://www.corp.google.com/eng/doc/devguide/cpp/primer.html#reference_members +/// Corresponding cpplint.py check name: 'runtime/member_string_reference'. +class MemberStringReferencesCheck : public ClangTidyCheck { +public: + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace runtime +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_MEMBER_STRING_REF_CHECK_H Index: clang-tidy/google/MemberStringReferencesCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/google/MemberStringReferencesCheck.cpp @@ -0,0 +1,48 @@ +//===--- MemberStringReferenceCheck.cpp - clang-tidy ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MemberStringReferencesCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/AST/ASTContext.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace runtime { + +void MemberStringReferencesCheck::registerMatchers( + ast_matchers::MatchFinder *Finder) { + // Look for const references to std::string or ::string. + auto String = anyOf(recordDecl(hasName("::std::basic_string")), + recordDecl(hasName("::string"))); + auto ConstString = qualType(isConstQualified(), hasDeclaration(String)); + + // Ignore members in templates. + auto InTemplate = hasAncestor( + decl(anyOf(recordDecl(ast_matchers::isTemplateInstantiation()), + functionDecl(ast_matchers::isTemplateInstantiation())))); + + Finder->addMatcher(fieldDecl(hasType(references(ConstString)), + unless(InTemplate)).bind("member"), + this); +} + +void +MemberStringReferencesCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Member = Result.Nodes.getNodeAs("member"); + diag(Member->getLocStart(), "const string& members are dangerous. It is much " + "better to use alternatives, such as pointers or " + "simple constants."); +} + +} // namespace runtime +} // namespace tidy +} // namespace clang