diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidByValueCaptureDefaultWhenCapturingThisCheck.h rename from clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h rename to clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidByValueCaptureDefaultWhenCapturingThisCheck.h --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidByValueCaptureDefaultWhenCapturingThisCheck.h @@ -1,4 +1,5 @@ -//===--- AvoidCaptureDefaultWhenCapturingThisCheck.h - clang-tidy*- C++ -*-===// +//===--- AvoidByValueCaptureDefaultWhenCapturingThisCheck.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,35 @@ // //===----------------------------------------------------------------------===// -#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_AVOIDBYVALUECAPTUREDEFAULTWHENCAPTURINGTHISCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDBYVALUECAPTUREDEFAULTWHENCAPTURINGTHISCHECK_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-by-value-capture-default-when-capturing-this.html +class AvoidByValueCaptureDefaultWhenCapturingThisCheck : public ClangTidyCheck { public: - AvoidCaptureDefaultWhenCapturingThisCheck(StringRef Name, - ClangTidyContext *Context); + AvoidByValueCaptureDefaultWhenCapturingThisCheck(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_AVOIDBYVALUECAPTUREDEFAULTWHENCAPTURINGTHISCHECK_H diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidByValueCaptureDefaultWhenCapturingThisCheck.cpp rename from clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp rename to clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidByValueCaptureDefaultWhenCapturingThisCheck.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidCaptureDefaultWhenCapturingThisCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidByValueCaptureDefaultWhenCapturingThisCheck.cpp @@ -1,4 +1,4 @@ -//===--- AvoidCaptureDefaultWhenCapturingThisCheck.cpp - clang-tidy--------===// +//===--- AvoidByValueCaptureDefaultWhenCapturingThisCheck.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 "AvoidByValueCaptureDefaultWhenCapturingThisCheck.h" #include "../utils/LexerUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -18,20 +18,12 @@ namespace clang::tidy::cppcoreguidelines { -AvoidCaptureDefaultWhenCapturingThisCheck:: - AvoidCaptureDefaultWhenCapturingThisCheck(StringRef Name, - ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - IgnoreCaptureDefaultByReference( - Options.get("IgnoreCaptureDefaultByReference", false)) {} +AvoidByValueCaptureDefaultWhenCapturingThisCheck:: + AvoidByValueCaptureDefaultWhenCapturingThisCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} -void AvoidCaptureDefaultWhenCapturingThisCheck::storeOptions( - ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "IgnoreCaptureDefaultByReference", - IgnoreCaptureDefaultByReference); -} - -void AvoidCaptureDefaultWhenCapturingThisCheck::registerMatchers( +void AvoidByValueCaptureDefaultWhenCapturingThisCheck::registerMatchers( MatchFinder *Finder) { Finder->addMatcher(lambdaExpr(hasAnyCapture(capturesThis())).bind("lambda"), this); @@ -85,23 +77,19 @@ return Replacement; } -void AvoidCaptureDefaultWhenCapturingThisCheck::check( +void AvoidByValueCaptureDefaultWhenCapturingThisCheck::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 + AvoidByValueCaptureDefaultWhenCapturingThisCheck.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,7 +14,7 @@ #include "../modernize/AvoidCArraysCheck.h" #include "../modernize/UseOverrideCheck.h" #include "../readability/MagicNumbersCheck.h" -#include "AvoidCaptureDefaultWhenCapturingThisCheck.h" +#include "AvoidByValueCaptureDefaultWhenCapturingThisCheck.h" #include "AvoidCapturingLambdaCoroutinesCheck.h" #include "AvoidConstOrRefDataMembersCheck.h" #include "AvoidDoWhileCheck.h" @@ -50,8 +50,9 @@ class CppCoreGuidelinesModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { - CheckFactories.registerCheck( - "cppcoreguidelines-avoid-capture-default-when-capturing-this"); + CheckFactories.registerCheck< + AvoidByValueCaptureDefaultWhenCapturingThisCheck>( + "cppcoreguidelines-avoid-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-this.rst @@ -1,11 +1,11 @@ -.. title:: clang-tidy - cppcoreguidelines-avoid-capture-default-when-capturing-this +.. title:: clang-tidy - cppcoreguidelines-avoid-by-value-capture-default-when-capturing-this -cppcoreguidelines-avoid-capture-default-when-capturing-this -=========================================================== +cppcoreguidelines-avoid-by-value-capture-default-when-capturing-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,7 +179,7 @@ `clang-analyzer-valist.Unterminated `_, `concurrency-mt-unsafe `_, `concurrency-thread-canceltype-asynchronous `_, - `cppcoreguidelines-avoid-capture-default-when-capturing-this `_, "Yes" + `cppcoreguidelines-avoid-by-value-capture-default-when-capturing-this `_, "Yes" `cppcoreguidelines-avoid-capturing-lambda-coroutines `_, `cppcoreguidelines-avoid-const-or-ref-data-members `_, `cppcoreguidelines-avoid-do-while `_, 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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-this %t struct Obj { void lambdas_that_warn_default_capture_copy() { @@ -9,73 +6,63 @@ 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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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-by-value-capture-default-when-capturing-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() {