diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidValueCaptureDefaultThisCheck.h rename from clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h rename to clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidValueCaptureDefaultThisCheck.h --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidValueCaptureDefaultThisCheck.h @@ -1,4 +1,5 @@ -//===--- AvoidCaptureDefaultWhenCapturingThisCheck.h - clang-tidy*- C++ -*-===// +//===--- AvoidValueCaptureDefaultThisCheck.h - clang-tidy*- C++ +//-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,39 +7,34 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDCAPTUREDEFAULTWHENCAPTURINGTHISCHECK_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDCAPTUREDEFAULTWHENCAPTURINGTHISCHECK_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDVALUECAPTUREDEFAULTTHISCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDVALUECAPTUREDEFAULTTHISCHECK_H #include "../ClangTidyCheck.h" namespace clang::tidy::cppcoreguidelines { -/// Warns when lambda specify a capture default and capture ``this``. The check -/// also offers fix-its. +/// Warns when lambda specify a by-value capture default and capture ``this``. +/// The check also offers fix-its. /// -/// Capture defaults in lambas defined within member functions can be +/// By-value capture defaults in lambas defined within member functions can be /// misleading about whether capturing data member is by value or reference. /// For example, [=] will capture local variables by value but member variables -/// by reference. CppCoreGuideline F.54 suggests to always be explicit -/// and never specify a capture default when also capturing this. +/// by reference. CppCoreGuideline F.54 suggests to never use by-value capture +/// default when capturing this. /// /// For the user-facing documentation see: -/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/avoid-capture-default-when-capturing-this.html -class AvoidCaptureDefaultWhenCapturingThisCheck : public ClangTidyCheck { +/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/avoid-value-capture-default-this.html +class AvoidValueCaptureDefaultThisCheck : public ClangTidyCheck { public: - AvoidCaptureDefaultWhenCapturingThisCheck(StringRef Name, - ClangTidyContext *Context); + AvoidValueCaptureDefaultThisCheck(StringRef Name, ClangTidyContext *Context); void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; - void storeOptions(ClangTidyOptions::OptionMap &Opts) override; bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus11; } - -private: - bool IgnoreCaptureDefaultByReference; }; } // namespace clang::tidy::cppcoreguidelines -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDCAPTUREDEFAULTWHENCAPTURINGTHISCHECK_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDVALUECAPTUREDEFAULTTHISCHECK_H diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidValueCaptureDefaultThisCheck.cpp rename from clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp rename to clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidValueCaptureDefaultThisCheck.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidValueCaptureDefaultThisCheck.cpp @@ -1,4 +1,4 @@ -//===--- AvoidCaptureDefaultWhenCapturingThisCheck.cpp - clang-tidy--------===// +//===--- AvoidValueCaptureDefaultThisCheck.cpp - clang-tidy----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "AvoidCaptureDefaultWhenCapturingThisCheck.h" +#include "AvoidValueCaptureDefaultThisCheck.h" #include "../utils/LexerUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -18,21 +18,11 @@ namespace clang::tidy::cppcoreguidelines { -AvoidCaptureDefaultWhenCapturingThisCheck:: - AvoidCaptureDefaultWhenCapturingThisCheck(StringRef Name, - ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - IgnoreCaptureDefaultByReference( - Options.get("IgnoreCaptureDefaultByReference", false)) {} +AvoidValueCaptureDefaultThisCheck::AvoidValueCaptureDefaultThisCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} -void AvoidCaptureDefaultWhenCapturingThisCheck::storeOptions( - ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IgnoreCaptureDefaultByReference", - IgnoreCaptureDefaultByReference); -} - -void AvoidCaptureDefaultWhenCapturingThisCheck::registerMatchers( - MatchFinder *Finder) { +void AvoidValueCaptureDefaultThisCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(lambdaExpr(hasAnyCapture(capturesThis())).bind("lambda"), this); } @@ -85,23 +75,19 @@ return Replacement; } -void AvoidCaptureDefaultWhenCapturingThisCheck::check( +void AvoidValueCaptureDefaultThisCheck::check( const MatchFinder::MatchResult &Result) { const auto *Lambda = Result.Nodes.getNodeAs("lambda"); if (!Lambda) return; - if (IgnoreCaptureDefaultByReference && - Lambda->getCaptureDefault() == LCD_ByRef) - return; - - if (Lambda->getCaptureDefault() != LCD_None) { + if (Lambda->getCaptureDefault() == LCD_ByCopy) { bool IsThisImplicitlyCaptured = std::any_of( Lambda->implicit_capture_begin(), Lambda->implicit_capture_end(), [](const LambdaCapture &Capture) { return Capture.capturesThis(); }); auto Diag = diag(Lambda->getCaptureDefaultLoc(), "lambdas that %select{|implicitly }0capture 'this' " - "should not specify a capture default") + "should not specify a by-value capture default") << IsThisImplicitlyCaptured; std::string ReplacementText = createReplacementText(Lambda); diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -4,7 +4,7 @@ ) add_clang_library(clangTidyCppCoreGuidelinesModule - AvoidCaptureDefaultWhenCapturingThisCheck.cpp + AvoidValueCaptureDefaultThisCheck.cpp AvoidCapturingLambdaCoroutinesCheck.cpp AvoidConstOrRefDataMembersCheck.cpp AvoidDoWhileCheck.cpp diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -14,13 +14,13 @@ #include "../modernize/AvoidCArraysCheck.h" #include "../modernize/UseOverrideCheck.h" #include "../readability/MagicNumbersCheck.h" -#include "AvoidCaptureDefaultWhenCapturingThisCheck.h" #include "AvoidCapturingLambdaCoroutinesCheck.h" #include "AvoidConstOrRefDataMembersCheck.h" #include "AvoidDoWhileCheck.h" #include "AvoidGotoCheck.h" #include "AvoidNonConstGlobalVariablesCheck.h" #include "AvoidReferenceCoroutineParametersCheck.h" +#include "AvoidValueCaptureDefaultThisCheck.h" #include "InitVariablesCheck.h" #include "InterfacesGlobalInitCheck.h" #include "MacroUsageCheck.h" @@ -50,8 +50,8 @@ class CppCoreGuidelinesModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { - CheckFactories.registerCheck( - "cppcoreguidelines-avoid-capture-default-when-capturing-this"); + CheckFactories.registerCheck( + "cppcoreguidelines-avoid-value-capture-default-this"); CheckFactories.registerCheck( "cppcoreguidelines-avoid-capturing-lambda-coroutines"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -112,8 +112,8 @@ This check relies heavily on, but is not exclusive to, the functions from the *Annex K. "Bounds-checking interfaces"* of C11. -- New :doc:`cppcoreguidelines-avoid-capture-default-when-capturing-this - ` check. +- New :doc:`cppcoreguidelines-avoid-value-capture-default-this + ` check. Warns when lambda specify a capture default and capture ``this``. diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-default-when-capturing-this.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-value-capture-default-this.rst rename from clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-default-when-capturing-this.rst rename to clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-value-capture-default-this.rst --- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-capture-default-when-capturing-this.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-value-capture-default-this.rst @@ -1,11 +1,11 @@ -.. title:: clang-tidy - cppcoreguidelines-avoid-capture-default-when-capturing-this +.. title:: clang-tidy - cppcoreguidelines-avoid-value-capture-default-this -cppcoreguidelines-avoid-capture-default-when-capturing-this -=========================================================== +cppcoreguidelines-avoid-value-capture-default-this +================================================== -Warns when lambda specify a capture default and capture ``this``. +Warns when lambda specify a by-value capture default and capture ``this``. -Capture-defaults in member functions can be misleading about +By-value capture-defaults in member functions can be misleading about whether data members are captured by value or reference. For example, specifying the capture default ``[=]`` will still capture data members by reference. @@ -40,14 +40,4 @@ }; This check implements -`CppCoreGuideline F.54 `_. - - -Options -------- - -.. option:: IgnoreCaptureDefaultByReference - - Do not warn when using capture default by reference. In this case, there is no - confusion as to whether variables are captured by value or reference. - Defaults to `false`. +`CppCoreGuideline F.54 `_. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -179,13 +179,13 @@ `clang-analyzer-valist.Unterminated `_, `concurrency-mt-unsafe `_, `concurrency-thread-canceltype-asynchronous `_, - `cppcoreguidelines-avoid-capture-default-when-capturing-this `_, "Yes" `cppcoreguidelines-avoid-capturing-lambda-coroutines `_, `cppcoreguidelines-avoid-const-or-ref-data-members `_, `cppcoreguidelines-avoid-do-while `_, `cppcoreguidelines-avoid-goto `_, `cppcoreguidelines-avoid-non-const-global-variables `_, `cppcoreguidelines-avoid-reference-coroutine-parameters `_, + `cppcoreguidelines-avoid-value-capture-default-this `_, "Yes" `cppcoreguidelines-init-variables `_, "Yes" `cppcoreguidelines-interfaces-global-init `_, `cppcoreguidelines-macro-usage `_, diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-value-capture-default-this.cpp rename from clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp rename to clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-value-capture-default-this.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-capture-default-when-capturing-this.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-value-capture-default-this.cpp @@ -1,7 +1,4 @@ -// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-default-when-capturing-this %t \ -// RUN: -check-suffixes=,DEFAULT -// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-capture-default-when-capturing-this %t \ -// RUN: -config="{CheckOptions: [{key: cppcoreguidelines-avoid-capture-default-when-capturing-this.IgnoreCaptureDefaultByReference, value: true}]}" +// RUN: %check_clang_tidy -std=c++11-or-later %s cppcoreguidelines-avoid-value-capture-default-this %t struct Obj { void lambdas_that_warn_default_capture_copy() { @@ -9,73 +6,60 @@ int local2{}; auto explicit_this_capture = [=, this]() { }; - // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto explicit_this_capture = [this]() { }; auto explicit_this_capture_locals1 = [=, this]() { return (local+x) > 10; }; - // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto explicit_this_capture_locals1 = [local, this]() { return (local+x) > 10; }; auto explicit_this_capture_locals2 = [=, this]() { return (local+local2) > 10; }; - // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: lambdas that capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto explicit_this_capture_locals2 = [local, local2, this]() { return (local+local2) > 10; }; auto explicit_this_capture_local_ref = [=, this, &local]() { return (local+x) > 10; }; - // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto explicit_this_capture_local_ref = [this, &local]() { return (local+x) > 10; }; auto explicit_this_capture_local_ref2 = [=, &local, this]() { return (local+x) > 10; }; - // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto explicit_this_capture_local_ref2 = [&local, this]() { return (local+x) > 10; }; auto explicit_this_capture_local_ref3 = [=, &local, this, &local2]() { return (local+x) > 10; }; - // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto explicit_this_capture_local_ref3 = [&local, this, &local2]() { return (local+x) > 10; }; auto explicit_this_capture_local_ref4 = [=, &local, &local2, this]() { return (local+x) > 10; }; - // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: lambdas that capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto explicit_this_capture_local_ref4 = [&local, &local2, this]() { return (local+x) > 10; }; auto explicit_this_capture_local_ref_extra_whitespace = [=, & local, &local2, this]() { return (local+x) > 10; }; - // CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:62: warning: lambdas that capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto explicit_this_capture_local_ref_extra_whitespace = [& local, &local2, this]() { return (local+x) > 10; }; auto explicit_this_capture_local_ref_with_comment = [=, & /* byref */ local, &local2, this]() { return (local+x) > 10; }; - // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: lambdas that capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto explicit_this_capture_local_ref_with_comment = [& /* byref */ local, &local2, this]() { return (local+x) > 10; }; auto implicit_this_capture = [=]() { return x > 10; }; - // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that implicitly capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: lambdas that implicitly capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto implicit_this_capture = [this]() { return x > 10; }; auto implicit_this_capture_local = [=]() { return (local+x) > 10; }; - // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: lambdas that implicitly capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] + // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: lambdas that implicitly capture 'this' should not specify a by-value capture default [cppcoreguidelines-avoid-value-capture-default-this] // CHECK-FIXES: auto implicit_this_capture_local = [local, this]() { return (local+x) > 10; }; } - void lambdas_that_warn_default_capture_ref() { + void lambdas_that_dont_warn_default_capture_ref() { int local{}; int local2{}; auto ref_explicit_this_capture = [&, this]() { }; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:39: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] - // CHECK-FIXES-DEFAULT: auto ref_explicit_this_capture = [this]() { }; - auto ref_explicit_this_capture_local = [&, this]() { return (local+x) > 10; }; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:45: warning: lambdas that capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] - // CHECK-FIXES-DEFAULT: auto ref_explicit_this_capture_local = [&local, this]() { return (local+x) > 10; }; auto ref_implicit_this_capture = [&]() { return x > 10; }; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:39: warning: lambdas that implicitly capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] - // CHECK-FIXES-DEFAULT: auto ref_implicit_this_capture = [this]() { return x > 10; }; - auto ref_implicit_this_capture_local = [&]() { return (local+x) > 10; }; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:45: warning: lambdas that implicitly capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] - // CHECK-FIXES-DEFAULT: auto ref_implicit_this_capture_local = [&local, this]() { return (local+x) > 10; }; - auto ref_implicit_this_capture_locals = [&]() { return (local+local2+x) > 10; }; - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:46: warning: lambdas that implicitly capture 'this' should not specify a capture default [cppcoreguidelines-avoid-capture-default-when-capturing-this] - // CHECK-FIXES-DEFAULT: auto ref_implicit_this_capture_locals = [&local, &local2, this]() { return (local+local2+x) > 10; }; } void lambdas_that_dont_warn() {