forked from OSchip/llvm-project
[clang-tidy] Adding Fuchsia checker for trailing returns
Adds a check to the Fuchsia module to warn if a function has a trailing return. See https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md for reference. Differential Revision: https://reviews.llvm.org/D42116 llvm-svn: 322759
This commit is contained in:
parent
75d7ee6af5
commit
93a88e33ef
|
@ -5,6 +5,7 @@ add_clang_library(clangTidyFuchsiaModule
|
|||
FuchsiaTidyModule.cpp
|
||||
OverloadedOperatorCheck.cpp
|
||||
StaticallyConstructedObjectsCheck.cpp
|
||||
TrailingReturnCheck.cpp
|
||||
VirtualInheritanceCheck.cpp
|
||||
|
||||
LINK_LIBS
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "DefaultArgumentsCheck.h"
|
||||
#include "OverloadedOperatorCheck.h"
|
||||
#include "StaticallyConstructedObjectsCheck.h"
|
||||
#include "TrailingReturnCheck.h"
|
||||
#include "VirtualInheritanceCheck.h"
|
||||
|
||||
using namespace clang::ast_matchers;
|
||||
|
@ -31,6 +32,8 @@ public:
|
|||
"fuchsia-overloaded-operator");
|
||||
CheckFactories.registerCheck<StaticallyConstructedObjectsCheck>(
|
||||
"fuchsia-statically-constructed-objects");
|
||||
CheckFactories.registerCheck<TrailingReturnCheck>(
|
||||
"fuchsia-trailing-return");
|
||||
CheckFactories.registerCheck<VirtualInheritanceCheck>(
|
||||
"fuchsia-virtual-inheritance");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
//===--- TrailingReturnCheck.cpp - clang-tidy------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "TrailingReturnCheck.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/ASTMatchers/ASTMatchersInternal.h"
|
||||
|
||||
using namespace clang::ast_matchers;
|
||||
|
||||
namespace clang {
|
||||
namespace ast_matchers {
|
||||
|
||||
const internal::VariadicDynCastAllOfMatcher<Type, DecltypeType> decltypeType;
|
||||
|
||||
} // namespace ast_matchers
|
||||
|
||||
namespace tidy {
|
||||
namespace fuchsia {
|
||||
|
||||
AST_MATCHER(FunctionDecl, hasTrailingReturn) {
|
||||
return Node.getType()->castAs<FunctionProtoType>()->hasTrailingReturn();
|
||||
}
|
||||
|
||||
void TrailingReturnCheck::registerMatchers(MatchFinder *Finder) {
|
||||
|
||||
// Requires C++11 or later.
|
||||
if (!getLangOpts().CPlusPlus11)
|
||||
return;
|
||||
|
||||
// Functions that have trailing returns are disallowed, except for those
|
||||
// using decltype specifiers and lambda with otherwise unutterable
|
||||
// return types.
|
||||
Finder->addMatcher(
|
||||
functionDecl(allOf(hasTrailingReturn(),
|
||||
unless(anyOf(returns(decltypeType()),
|
||||
hasParent(cxxRecordDecl(isLambda()))))))
|
||||
.bind("decl"),
|
||||
this);
|
||||
}
|
||||
|
||||
void TrailingReturnCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
if (const auto *D = Result.Nodes.getNodeAs<Decl>("decl"))
|
||||
diag(D->getLocStart(),
|
||||
"a trailing return type is disallowed for this type of declaration");
|
||||
}
|
||||
|
||||
} // namespace fuchsia
|
||||
} // namespace tidy
|
||||
} // namespace clang
|
|
@ -0,0 +1,37 @@
|
|||
//===--- TrailingReturnCheck.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_FUCHSIA_TRAILING_RETURN_H
|
||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_TRAILING_RETURN_H
|
||||
|
||||
#include "../ClangTidy.h"
|
||||
|
||||
namespace clang {
|
||||
namespace tidy {
|
||||
namespace fuchsia {
|
||||
|
||||
/// Functions that have trailing returns are disallowed, except for those
|
||||
/// using decltype specifiers and lambda with otherwise unutterable
|
||||
/// return types.
|
||||
///
|
||||
/// For the user-facing documentation see:
|
||||
/// http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-trailing-return.html
|
||||
class TrailingReturnCheck : public ClangTidyCheck {
|
||||
public:
|
||||
TrailingReturnCheck(StringRef Name, ClangTidyContext *Context)
|
||||
: ClangTidyCheck(Name, Context) {}
|
||||
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||
};
|
||||
|
||||
} // namespace fuchsia
|
||||
} // namespace tidy
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_TRAILING_RETURN_H
|
|
@ -70,7 +70,14 @@ Improvements to clang-tidy
|
|||
Warns if global, non-trivial objects with static storage are constructed, unless the
|
||||
object is statically initialized with a ``constexpr`` constructor or has no
|
||||
explicit constructor.
|
||||
|
||||
- New `fuchsia-trailing-return
|
||||
<http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-trailing-return.html>`_ check
|
||||
|
||||
Functions that have trailing returns are disallowed, except for those
|
||||
using decltype specifiers and lambda with otherwise unutterable
|
||||
return types.
|
||||
|
||||
- New alias `hicpp-avoid-goto
|
||||
<http://clang.llvm.org/extra/clang-tidy/checks/hicpp-avoid-goto.html>`_ to
|
||||
`cppcoreguidelines-avoid-goto <http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-avoid-goto.html>`_
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
.. title:: clang-tidy - fuchsia-trailing-return
|
||||
|
||||
fuchsia-trailing-return
|
||||
=======================
|
||||
|
||||
Functions that have trailing returns are disallowed, except for those using
|
||||
decltype specifiers and lambda with otherwise unutterable return types.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// No warning
|
||||
int add_one(const int arg) { return arg; }
|
||||
|
||||
// Warning
|
||||
auto get_add_one() -> int (*)(const int) {
|
||||
return add_one;
|
||||
}
|
||||
|
||||
Exceptions are made for lambdas and decltype specifiers:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// No warning
|
||||
auto lambda = [](double x, double y) -> double {return x + y;};
|
||||
|
||||
// No warning
|
||||
template <typename T1, typename T2>
|
||||
auto fn(const T1 &lhs, const T2 &rhs) -> decltype(lhs + rhs) {
|
||||
return lhs + rhs;
|
||||
}
|
||||
|
||||
|
||||
See the features disallowed in Fuchsia at https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md
|
|
@ -72,6 +72,7 @@ Clang-Tidy Checks
|
|||
fuchsia-default-arguments
|
||||
fuchsia-overloaded-operator
|
||||
fuchsia-statically-constructed-objects
|
||||
fuchsia-trailing-return
|
||||
fuchsia-virtual-inheritance
|
||||
google-build-explicit-make-pair
|
||||
google-build-namespaces
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// RUN: %check_clang_tidy %s fuchsia-trailing-return %t
|
||||
|
||||
int add_one(const int arg) { return arg; }
|
||||
|
||||
auto get_add_one() -> int (*)(const int) {
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: a trailing return type is disallowed for this type of declaration
|
||||
// CHECK-NEXT: auto get_add_one() -> int (*)(const int) {
|
||||
return add_one;
|
||||
}
|
||||
|
||||
auto lambda = [](double x, double y) {return x + y;};
|
||||
|
||||
auto lambda2 = [](double x, double y) -> double {return x + y;};
|
||||
|
||||
int main() {
|
||||
get_add_one()(5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
auto fn(const T1 &lhs, const T2 &rhs) -> decltype(lhs + rhs) {
|
||||
return lhs + rhs;
|
||||
}
|
Loading…
Reference in New Issue