File tree Expand file tree Collapse file tree 5 files changed +68
-3
lines changed Expand file tree Collapse file tree 5 files changed +68
-3
lines changed Original file line number Diff line number Diff line change @@ -120,7 +120,7 @@ void MissingStdForwardCheck::registerMatchers(MatchFinder *Finder) {
120120 equalsBoundNode (" param" ), equalsBoundNode (" var" )))))),
121121 CapturedInLambda)),
122122 callee (unresolvedLookupExpr (hasAnyDeclaration (
123- namedDecl (hasUnderlyingDecl (hasName (" ::std::forward " )))))),
123+ namedDecl (hasUnderlyingDecl (hasName (ForwardFunction )))))),
124124
125125 unless (anyOf (hasAncestor (typeLoc ()),
126126 hasAncestor (expr (hasUnevaluatedContext ())))));
@@ -149,4 +149,13 @@ void MissingStdForwardCheck::check(const MatchFinder::MatchResult &Result) {
149149 << Param;
150150}
151151
152+ MissingStdForwardCheck::MissingStdForwardCheck (StringRef Name,
153+ ClangTidyContext *Context)
154+ : ClangTidyCheck(Name, Context),
155+ ForwardFunction (Options.get(" ForwardFunction" , " ::std::forward" )) {}
156+
157+ void MissingStdForwardCheck::storeOptions (ClangTidyOptions::OptionMap &Opts) {
158+ Options.store (Opts, " ForwardFunction" , ForwardFunction);
159+ }
160+
152161} // namespace clang::tidy::cppcoreguidelines
Original file line number Diff line number Diff line change @@ -21,8 +21,7 @@ namespace clang::tidy::cppcoreguidelines {
2121// / http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/missing-std-forward.html
2222class MissingStdForwardCheck : public ClangTidyCheck {
2323public:
24- MissingStdForwardCheck (StringRef Name, ClangTidyContext *Context)
25- : ClangTidyCheck(Name, Context) {}
24+ MissingStdForwardCheck (StringRef Name, ClangTidyContext *Context);
2625 void registerMatchers (ast_matchers::MatchFinder *Finder) override ;
2726 void check (const ast_matchers::MatchFinder::MatchResult &Result) override ;
2827 bool isLanguageVersionSupported (const LangOptions &LangOpts) const override {
@@ -31,6 +30,10 @@ class MissingStdForwardCheck : public ClangTidyCheck {
3130 std::optional<TraversalKind> getCheckTraversalKind () const override {
3231 return TK_IgnoreUnlessSpelledInSource;
3332 }
33+ void storeOptions (ClangTidyOptions::OptionMap &Opts) override ;
34+
35+ private:
36+ const StringRef ForwardFunction;
3437};
3538
3639} // namespace clang::tidy::cppcoreguidelines
Original file line number Diff line number Diff line change @@ -212,6 +212,10 @@ Changes in existing checks
212212 <clang-tidy/checks/cppcoreguidelines/avoid-goto>` check by adding the option
213213 `IgnoreMacros ` to ignore ``goto `` labels defined in macros.
214214
215+ - Improved :doc: `cppcoreguidelines-missing-std-forward
216+ <clang-tidy/checks/cppcoreguidelines/missing-std-forward>` check by adding a
217+ flag to specify the function used for forwarding instead of ``std::forward ``.
218+
215219- Improved :doc: `cppcoreguidelines-special-member-functions
216220 <clang-tidy/checks/cppcoreguidelines/special-member-functions>` check by
217221 adding the option `IgnoreMacros ` to ignore classes defined in macros.
Original file line number Diff line number Diff line change @@ -35,6 +35,13 @@ Example:
3535 f(1, 2); // Incorrect - may not invoke the desired qualified function operator
3636 }
3737
38+ Options
39+ -------
40+
41+ .. option :: ForwardFunction
42+
43+ Specify the function used for forwarding. Default is `::std::forward `.
44+
3845This check implements `F.19
3946<http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-forward> `_
4047from the C++ Core Guidelines.
Original file line number Diff line number Diff line change 1+ // RUN: %check_clang_tidy -std=c++14 %s cppcoreguidelines-missing-std-forward %t -- \
2+ // RUN: -config="{CheckOptions: {cppcoreguidelines-missing-std-forward.ForwardFunction: custom_forward}}" -- -fno-delayed-template-parsing
3+
4+ // NOLINTBEGIN
5+ namespace std {
6+
7+ template <typename T> struct remove_reference { using type = T; };
8+ template <typename T> struct remove_reference <T&> { using type = T; };
9+ template <typename T> struct remove_reference <T&&> { using type = T; };
10+
11+ template <typename T> using remove_reference_t = typename remove_reference<T>::type;
12+
13+ template <typename T> constexpr T &&forward(remove_reference_t <T> &t) noexcept ;
14+ template <typename T> constexpr T &&forward(remove_reference_t <T> &&t) noexcept ;
15+ template <typename T> constexpr remove_reference_t <T> &&move(T &&x);
16+
17+ } // namespace std
18+ // NOLINTEND
19+
20+ template <class T >
21+ constexpr decltype (auto ) custom_forward(std::remove_reference_t <T>& tmp) noexcept
22+ {
23+ return static_cast <T&&>(tmp);
24+ }
25+
26+ template <class T >
27+ constexpr decltype (auto ) custom_forward(std::remove_reference_t <T>&& tmp) noexcept
28+ {
29+ return static_cast <T&&>(tmp);
30+ }
31+
32+ template <class T >
33+ void forward_with_std (T&& t) {
34+ // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]
35+
36+ T other{std::forward<T>(t)};
37+ }
38+
39+ template <class T >
40+ void move_with_custom (T&& t) {
41+ T other{custom_forward<T>(t)};
42+ }
You can’t perform that action at this time.
0 commit comments