forked from OSchip/llvm-project
[clang-tidy] Add a checker that warns on const string & members.
Summary: Those are considered unsafe and should be replaced with simple pointers or full copies. It recognizes both std::string and ::string. Reviewers: alexfh, djasper Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D4522 llvm-svn: 213133
This commit is contained in:
parent
2e9427a175
commit
b1039759fb
|
@ -7,6 +7,7 @@ add_clang_library(clangTidyGoogleModule
|
|||
GoogleTidyModule.cpp
|
||||
NamedParameterCheck.cpp
|
||||
OverloadedUnaryAndCheck.cpp
|
||||
StringReferenceMemberCheck.cpp
|
||||
|
||||
LINK_LIBS
|
||||
clangAST
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "ExplicitMakePairCheck.h"
|
||||
#include "NamedParameterCheck.h"
|
||||
#include "OverloadedUnaryAndCheck.h"
|
||||
#include "StringReferenceMemberCheck.h"
|
||||
|
||||
using namespace clang::ast_matchers;
|
||||
|
||||
|
@ -33,6 +34,9 @@ public:
|
|||
CheckFactories.addCheckFactory(
|
||||
"google-runtime-operator",
|
||||
new ClangTidyCheckFactory<runtime::OverloadedUnaryAndCheck>());
|
||||
CheckFactories.addCheckFactory(
|
||||
"google-runtime-member-string-references",
|
||||
new ClangTidyCheckFactory<runtime::StringReferenceMemberCheck>());
|
||||
CheckFactories.addCheckFactory(
|
||||
"google-readability-casting",
|
||||
new ClangTidyCheckFactory<readability::AvoidCStyleCastsCheck>());
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
//===--- StringReferenceMemberCheck.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 "StringReferenceMemberCheck.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 StringReferenceMemberCheck::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 template instantiations.
|
||||
auto InTemplateInstantiation = hasAncestor(
|
||||
decl(anyOf(recordDecl(ast_matchers::isTemplateInstantiation()),
|
||||
functionDecl(ast_matchers::isTemplateInstantiation()))));
|
||||
|
||||
Finder->addMatcher(fieldDecl(hasType(references(ConstString)),
|
||||
unless(InTemplateInstantiation)).bind("member"),
|
||||
this);
|
||||
}
|
||||
|
||||
void
|
||||
StringReferenceMemberCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
const auto *Member = Result.Nodes.getNodeAs<FieldDecl>("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
|
|
@ -0,0 +1,50 @@
|
|||
//===--- StringReferenceMemberCheck.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_STRING_REF_MEMBER_CHECK_H
|
||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_STRING_REF_MEMBER_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 as they can
|
||||
/// be created from a temporary quite easily.
|
||||
///
|
||||
/// \code
|
||||
/// struct S {
|
||||
/// S(const string &Str) : Str(Str) {}
|
||||
/// const string &Str;
|
||||
/// };
|
||||
/// S instance("string");
|
||||
/// \endcode
|
||||
///
|
||||
/// In the constructor call a string temporary is created from const char * and
|
||||
/// destroyed immediately after the call. This leaves around a dangling
|
||||
/// reference.
|
||||
///
|
||||
/// This check emit warnings for both std::string and ::string const reference
|
||||
/// members.
|
||||
///
|
||||
/// Corresponding cpplint.py check name: 'runtime/member_string_reference'.
|
||||
class StringReferenceMemberCheck : 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_STRING_REF_MEMBER_CHECK_H
|
|
@ -0,0 +1,49 @@
|
|||
// RUN: clang-tidy %s -checks='-*,google-runtime-member-string-references' -- | FileCheck %s -implicit-check-not="{{warning|error}}:"
|
||||
|
||||
namespace std {
|
||||
template<typename T>
|
||||
class basic_string {};
|
||||
|
||||
typedef basic_string<char> string;
|
||||
}
|
||||
|
||||
class string {};
|
||||
|
||||
|
||||
struct A {
|
||||
const std::string &s;
|
||||
// CHECK: :[[@LINE-1]]:3: warning: const string& members are dangerous. It is much better to use alternatives, such as pointers or simple constants.
|
||||
};
|
||||
|
||||
struct B {
|
||||
std::string &s;
|
||||
};
|
||||
|
||||
struct C {
|
||||
const std::string s;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct D {
|
||||
D();
|
||||
const T &s;
|
||||
const std::string &s2;
|
||||
// CHECK: :[[@LINE-1]]:3: warning: const string& members are dangerous. It is much better to use alternatives, such as pointers or simple constants.
|
||||
};
|
||||
|
||||
D<std::string> d;
|
||||
|
||||
struct AA {
|
||||
const string &s;
|
||||
// CHECK: :[[@LINE-1]]:3: warning: const string& members are dangerous. It is much better to use alternatives, such as pointers or simple constants.
|
||||
};
|
||||
|
||||
struct BB {
|
||||
string &s;
|
||||
};
|
||||
|
||||
struct CC {
|
||||
const string s;
|
||||
};
|
||||
|
||||
D<string> dd;
|
Loading…
Reference in New Issue