https://github.com/OmarAzizi updated https://github.com/llvm/llvm-project/pull/190438
>From b1de6aa2612f0897cc544444070130b0691003a1 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Sat, 4 Apr 2026 03:45:48 +0300 Subject: [PATCH 01/13] [clang-tidy] Add readability-redundant-lambda-parentheses check --- .../clang-tidy/readability/CMakeLists.txt | 1 + .../readability/ReadabilityTidyModule.cpp | 3 + .../RedundantLambdaParenthesesCheck.cpp | 90 +++++++++++++++++++ .../RedundantLambdaParenthesesCheck.h | 34 +++++++ clang-tools-extra/docs/ReleaseNotes.rst | 5 ++ .../docs/clang-tidy/checks/list.rst | 3 +- .../redundant-lambda-parentheses.rst | 35 ++++++++ .../redundant-lambda-parentheses-cxx20.cpp | 19 ++++ .../redundant-lambda-parentheses-cxx23.cpp | 41 +++++++++ .../redundant-lambda-parentheses.cpp | 38 ++++++++ 10 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/redundant-lambda-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index 686e7c19d650b..3702600e0496c 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -44,6 +44,7 @@ add_clang_library(clangTidyReadabilityModule STATIC RedundantControlFlowCheck.cpp RedundantDeclarationCheck.cpp RedundantFunctionPtrDereferenceCheck.cpp + RedundantLambdaParenthesesCheck.cpp RedundantMemberInitCheck.cpp RedundantParenthesesCheck.cpp RedundantPreprocessorCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index 8e9e00b23c84a..6bfeb6c548f48 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -46,6 +46,7 @@ #include "RedundantDeclarationCheck.h" #include "RedundantFunctionPtrDereferenceCheck.h" #include "RedundantInlineSpecifierCheck.h" +#include "RedundantLambdaParenthesesCheck.h" #include "RedundantMemberInitCheck.h" #include "RedundantParenthesesCheck.h" #include "RedundantPreprocessorCheck.h" @@ -143,6 +144,8 @@ class ReadabilityModule : public ClangTidyModule { "readability-redundant-casting"); CheckFactories.registerCheck<RedundantFunctionPtrDereferenceCheck>( "readability-redundant-function-ptr-dereference"); + CheckFactories.registerCheck<RedundantLambdaParenthesesCheck>( + "readability-redundant-lambda-parentheses"); CheckFactories.registerCheck<RedundantMemberInitCheck>( "readability-redundant-member-init"); CheckFactories.registerCheck<RedundantParenthesesCheck>( diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp new file mode 100644 index 0000000000000..275eba3448d4c --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "RedundantLambdaParenthesesCheck.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void RedundantLambdaParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(lambdaExpr().bind("lambda"), this); +} + +void RedundantLambdaParenthesesCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *Lambda = Result.Nodes.getNodeAs<LambdaExpr>("lambda"); + + if (Lambda->getBeginLoc().isMacroID()) + return; + + if (!Lambda->hasExplicitParameters() && !Lambda->isGenericLambda()) + return; + + if (Lambda->getCallOperator()->getNumParams() != 0) + return; + + if (Lambda->isGenericLambda() && !getLangOpts().CPlusPlus20) + return; + + const LangOptions &LangOpts = getLangOpts(); + + SourceLocation ScanFrom; + if (Lambda->isGenericLambda()) { + TemplateParameterList *TPL = Lambda->getTemplateParameterList(); + ScanFrom = Lexer::getLocForEndOfToken(TPL->getRAngleLoc(), 0, + *Result.SourceManager, LangOpts); + } else { + ScanFrom = Lexer::getLocForEndOfToken(Lambda->getIntroducerRange().getEnd(), + 0, *Result.SourceManager, LangOpts); + } + + Token Tok; + if (Lexer::getRawToken(ScanFrom, Tok, *Result.SourceManager, LangOpts, + /*IgnoreWhiteSpace=*/true)) + return; + + if (Tok.isNot(tok::l_paren)) + return; + + SourceLocation LParenLoc = Tok.getLocation(); + SourceLocation RParenLoc = Lexer::findLocationAfterToken( + LParenLoc, tok::r_paren, *Result.SourceManager, LangOpts, + /*SkipTrailingWhitespaceAndNewLine=*/false); + + if (LParenLoc.isInvalid() || RParenLoc.isInvalid()) + return; + + if (!LangOpts.CPlusPlus23) { + std::optional<Token> RParen = + Lexer::findNextToken(LParenLoc, *Result.SourceManager, LangOpts); + if (!RParen || RParen->isNot(tok::r_paren)) + return; + std::optional<Token> NextTok = Lexer::findNextToken( + RParen->getLocation(), *Result.SourceManager, LangOpts); + if (NextTok && NextTok->is(tok::raw_identifier)) { + StringRef Id = NextTok->getRawIdentifier(); + if (Id == "constexpr" || Id == "consteval" || Id == "mutable" || + Id == "noexcept") + return; + } + if (NextTok && NextTok->is(tok::arrow)) + return; + } + + CharSourceRange ParenRange = + CharSourceRange::getCharRange(LParenLoc, RParenLoc); + + diag(LParenLoc, "redundant empty parameter list in lambda expression") + << FixItHint::CreateRemoval(ParenRange); +} + +} // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h new file mode 100644 index 0000000000000..3437d703da1f4 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTLAMBDAPARENTHESESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTLAMBDAPARENTHESESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Finds lambda expressions with a redundant empty parameter list and removes +/// it. +/// +/// For the user-facing documentation see: +/// https://clang.llvm.org/extra/clang-tidy/checks/readability/redundant-lambda-parentheses.html +class RedundantLambdaParenthesesCheck : public ClangTidyCheck { +public: + RedundantLambdaParenthesesCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } +}; + +} // namespace clang::tidy::readability + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANTLAMBDAPARENTHESESCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 36e311341f336..9672664901f0a 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -163,6 +163,11 @@ New checks Suggests insertion of ``std::move(...)`` to turn copy assignment operator calls into move assignment ones, when deemed valid and profitable. +- New :doc:`readability-redundant-lambda-parentheses + <clang-tidy/checks/readability/redundant-lambda-parentheses>` check. + + FIXME: Write a short description. + - New :doc:`readability-redundant-qualified-alias <clang-tidy/checks/readability/redundant-qualified-alias>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 2b5be931271ec..3f69d9f51d73f 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -241,7 +241,6 @@ Clang-Tidy Checks :doc:`google-runtime-int <google/runtime-int>`, :doc:`google-runtime-operator <google/runtime-operator>`, :doc:`google-upgrade-googletest-case <google/upgrade-googletest-case>`, "Yes" - :doc:`hicpp-exception-baseclass <hicpp/exception-baseclass>`, :doc:`hicpp-multiway-paths-covered <hicpp/multiway-paths-covered>`, :doc:`hicpp-signed-bitwise <hicpp/signed-bitwise>`, :doc:`linuxkernel-must-check-errs <linuxkernel/must-check-errs>`, @@ -351,7 +350,6 @@ Clang-Tidy Checks :doc:`openmp-use-default-none <openmp/use-default-none>`, :doc:`performance-avoid-endl <performance/avoid-endl>`, "Yes" :doc:`performance-enum-size <performance/enum-size>`, - :doc:`performance-faster-string-find <performance/faster-string-find>`, "Yes" :doc:`performance-for-range-copy <performance/for-range-copy>`, "Yes" :doc:`performance-implicit-conversion-in-loop <performance/implicit-conversion-in-loop>`, :doc:`performance-inefficient-algorithm <performance/inefficient-algorithm>`, "Yes" @@ -415,6 +413,7 @@ Clang-Tidy Checks :doc:`readability-redundant-declaration <readability/redundant-declaration>`, "Yes" :doc:`readability-redundant-function-ptr-dereference <readability/redundant-function-ptr-dereference>`, "Yes" :doc:`readability-redundant-inline-specifier <readability/redundant-inline-specifier>`, "Yes" + :doc:`readability-redundant-lambda-parentheses <readability/redundant-lambda-parentheses>`, "Yes" :doc:`readability-redundant-member-init <readability/redundant-member-init>`, "Yes" :doc:`readability-redundant-parentheses <readability/redundant-parentheses>`, "Yes" :doc:`readability-redundant-preprocessor <readability/redundant-preprocessor>`, diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-lambda-parentheses.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-lambda-parentheses.rst new file mode 100644 index 0000000000000..3167b841b38bc --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-lambda-parentheses.rst @@ -0,0 +1,35 @@ +.. title:: clang-tidy - readability-redundant-lambda-parentheses + +readability-redundant-lambda-parentheses +======================================== + +Finds lambda expressions with a redundant empty parameter list and removes it. + +In C++11 and later, a lambda with no parameters does not require an explicit +``()`` unless it has a specifier such as ``mutable``, ``noexcept``, or a +trailing return type. In C++23 and later, ``()`` is redundant even when such +specifiers are present. + +.. code-block:: c++ + + // C++11 and later - the following lambdas will be rewritten: + auto a = []() { return 42; }; + // becomes: + auto a = [] { return 42; }; + + auto b = [x = 1]() { return x; }; + // becomes: + auto b = [x = 1] { return x; }; + + // C++23 and later - the following lambdas will also be rewritten: + auto c = []() mutable {}; + // becomes: + auto c = [] mutable {}; + + auto d = []() noexcept {}; + // becomes: + auto d = [] noexcept {}; + + auto e = []() -> int { return 0; }; + // becomes: + auto e = [] -> int { return 0; }; \ No newline at end of file diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp new file mode 100644 index 0000000000000..769ffad629d03 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp @@ -0,0 +1,19 @@ +// RUN: %check_clang_tidy -std=c++20 %s readability-redundant-lambda-parentheses %t + +int main() { + // Generic lambdas - should warn in C++20 and later + auto a = []<class T>() { return sizeof(T); }; + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto a = []<class T> { return sizeof(T); };{{$}} + + auto b = []<class T>() requires true { return sizeof(T); }; + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto b = []<class T> requires true { return sizeof(T); };{{$}} + + // Should NOT warn - has parameters + auto c = []<class T>(T x) { return x; }; + + // Should NOT warn - has specifiers + auto d = []<class T>() mutable { return sizeof(T); }; + auto e = []<class T>() noexcept { return sizeof(T); }; +} \ No newline at end of file diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp new file mode 100644 index 0000000000000..4a9378564c149 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp @@ -0,0 +1,41 @@ +// RUN: %check_clang_tidy -std=c++23 %s readability-redundant-lambda-parentheses %t + +int main() { + // Basic cases - should warn + auto a = []() { return 42; }; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto a = [] { return 42; };{{$}} + + // Specifier cases - should also warn in C++23 + auto b = []() mutable {}; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto b = [] mutable {};{{$}} + + auto c = []() noexcept {}; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto c = [] noexcept {};{{$}} + + auto d = []() -> int { return 0; }; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto d = [] -> int { return 0; };{{$}} + + auto e = []() mutable noexcept {}; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto e = [] mutable noexcept {};{{$}} + + auto f = []() constexpr { return 42; }; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto f = [] constexpr { return 42; };{{$}} + + auto g = []() consteval { return 42; }; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto g = [] consteval { return 42; };{{$}} + + // Should NOT warn - has parameters + auto h = [](int x) { return x; }; + + // Should NOT warn - macro +#define LAMBDA []() { return 42; } + auto i = LAMBDA; +#undef LAMBDA +} \ No newline at end of file diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp new file mode 100644 index 0000000000000..e04dca093dba5 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp @@ -0,0 +1,38 @@ +// RUN: %check_clang_tidy -std=c++17 %s readability-redundant-lambda-parentheses %t + +int main() { + // Basic cases - should warn + auto a = []() { return 42; }; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto a = [] { return 42; };{{$}} + + auto b = [x = 1]() { return x; }; + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto b = [x = 1] { return x; };{{$}} + + // Lambda with no captures + auto c = []() {}; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto c = [] {};{{$}} + + // Lambda inside a function call + auto v = 1; + auto call = [&v]() { return v; }; + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: {{^}} auto call = [&v] { return v; };{{$}} + + // Should NOT warn - has parameters + auto d = [](int x) { return x; }; + auto e = [](int x, int y) { return x + y; }; + + // Should NOT warn - has specifiers, needs C++23 + auto f = []() mutable {}; + auto g = []() noexcept {}; + auto h = []() -> int { return 0; }; + auto i = []() constexpr { return 42; }; + + // Should NOT warn - macro +#define LAMBDA []() { return 42; } + auto k = LAMBDA; +#undef LAMBDA +} \ No newline at end of file >From b9cd06c0503c495121ce87e50a76316a87bd8125 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Sat, 4 Apr 2026 04:13:45 +0300 Subject: [PATCH 02/13] [clang-tidy] Fix missing newlines, release notes, and list.rst entries --- clang-tools-extra/docs/ReleaseNotes.rst | 3 ++- clang-tools-extra/docs/clang-tidy/checks/list.rst | 2 ++ .../checks/readability/redundant-lambda-parentheses.rst | 2 +- .../readability/redundant-lambda-parentheses-cxx20.cpp | 2 +- .../readability/redundant-lambda-parentheses-cxx23.cpp | 2 +- .../checkers/readability/redundant-lambda-parentheses.cpp | 2 +- 6 files changed, 8 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 9672664901f0a..4265710225b56 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -166,7 +166,8 @@ New checks - New :doc:`readability-redundant-lambda-parentheses <clang-tidy/checks/readability/redundant-lambda-parentheses>` check. - FIXME: Write a short description. + Finds and removes redundant empty parameter lists from lambda expressions + when the rewrite is valid for the active language standard. - New :doc:`readability-redundant-qualified-alias <clang-tidy/checks/readability/redundant-qualified-alias>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 3f69d9f51d73f..864df613a332a 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -241,6 +241,7 @@ Clang-Tidy Checks :doc:`google-runtime-int <google/runtime-int>`, :doc:`google-runtime-operator <google/runtime-operator>`, :doc:`google-upgrade-googletest-case <google/upgrade-googletest-case>`, "Yes" + :doc:`hicpp-exception-baseclass <hicpp/exception-baseclass>`, :doc:`hicpp-multiway-paths-covered <hicpp/multiway-paths-covered>`, :doc:`hicpp-signed-bitwise <hicpp/signed-bitwise>`, :doc:`linuxkernel-must-check-errs <linuxkernel/must-check-errs>`, @@ -350,6 +351,7 @@ Clang-Tidy Checks :doc:`openmp-use-default-none <openmp/use-default-none>`, :doc:`performance-avoid-endl <performance/avoid-endl>`, "Yes" :doc:`performance-enum-size <performance/enum-size>`, + :doc:`performance-faster-string-find <performance/faster-string-find>`, "Yes" :doc:`performance-for-range-copy <performance/for-range-copy>`, "Yes" :doc:`performance-implicit-conversion-in-loop <performance/implicit-conversion-in-loop>`, :doc:`performance-inefficient-algorithm <performance/inefficient-algorithm>`, "Yes" diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-lambda-parentheses.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-lambda-parentheses.rst index 3167b841b38bc..04b870830bedf 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-lambda-parentheses.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/redundant-lambda-parentheses.rst @@ -32,4 +32,4 @@ specifiers are present. auto e = []() -> int { return 0; }; // becomes: - auto e = [] -> int { return 0; }; \ No newline at end of file + auto e = [] -> int { return 0; }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp index 769ffad629d03..e28da89a8ad6f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp @@ -16,4 +16,4 @@ int main() { // Should NOT warn - has specifiers auto d = []<class T>() mutable { return sizeof(T); }; auto e = []<class T>() noexcept { return sizeof(T); }; -} \ No newline at end of file +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp index 4a9378564c149..21a6e90508530 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp @@ -38,4 +38,4 @@ int main() { #define LAMBDA []() { return 42; } auto i = LAMBDA; #undef LAMBDA -} \ No newline at end of file +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp index e04dca093dba5..2e7fe14f5da29 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp @@ -35,4 +35,4 @@ int main() { #define LAMBDA []() { return 42; } auto k = LAMBDA; #undef LAMBDA -} \ No newline at end of file +} >From 4063ef5569b7996c0e4c4cf626793a4b9d5ad624 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Sat, 4 Apr 2026 04:33:58 +0300 Subject: [PATCH 03/13] [clang-tidy] Remove unnecessary includes --- .../clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp index 275eba3448d4c..90b1237cf5987 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp @@ -7,8 +7,6 @@ //===----------------------------------------------------------------------===// #include "RedundantLambdaParenthesesCheck.h" -#include "clang/AST/DeclTemplate.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; >From 53d2c84879d8ae09c0b14f1d348be56a7f5ccff5 Mon Sep 17 00:00:00 2001 From: Kryptonite <[email protected]> Date: Sat, 4 Apr 2026 07:47:48 +0300 Subject: [PATCH 04/13] "[clang-tidy] Sync release notes with check documentation --- clang-tools-extra/docs/ReleaseNotes.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 4265710225b56..24d4ad2abe64d 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -166,8 +166,7 @@ New checks - New :doc:`readability-redundant-lambda-parentheses <clang-tidy/checks/readability/redundant-lambda-parentheses>` check. - Finds and removes redundant empty parameter lists from lambda expressions - when the rewrite is valid for the active language standard. + Finds lambda expressions with a redundant empty parameter list and removes it. - New :doc:`readability-redundant-qualified-alias <clang-tidy/checks/readability/redundant-qualified-alias>` check. >From 15cea8ad210f838eaf0da36ec0248f0536ff92b6 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Sat, 4 Apr 2026 19:08:59 +0300 Subject: [PATCH 05/13] [clang-tidy] Address review: move checks into matchers and add TK_IgnoreUnlessSpelledInSource --- .../RedundantLambdaParenthesesCheck.cpp | 59 +++++++++++-------- .../RedundantLambdaParenthesesCheck.h | 5 ++ 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp index 90b1237cf5987..9241352e09cf4 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp @@ -7,43 +7,56 @@ //===----------------------------------------------------------------------===// #include "RedundantLambdaParenthesesCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; +namespace { + +AST_MATCHER(clang::LambdaExpr, hasNoParameters) { + return Node.getCallOperator()->getNumParams() == 0; +} + +AST_MATCHER(clang::LambdaExpr, hasExplicitOrGenericParameters) { + return Node.hasExplicitParameters() || Node.isGenericLambda(); +} + +AST_MATCHER(clang::LambdaExpr, isGenericLambdaInCxx20OrLater) { + return !Node.isGenericLambda() || + Finder->getASTContext().getLangOpts().CPlusPlus20; +} + +} // namespace + namespace clang::tidy::readability { void RedundantLambdaParenthesesCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(lambdaExpr().bind("lambda"), this); + Finder->addMatcher( + lambdaExpr(hasExplicitOrGenericParameters(), hasNoParameters(), + isGenericLambdaInCxx20OrLater()) + .bind("lambda"), + this); } void RedundantLambdaParenthesesCheck::check( const MatchFinder::MatchResult &Result) { const auto *Lambda = Result.Nodes.getNodeAs<LambdaExpr>("lambda"); - if (Lambda->getBeginLoc().isMacroID()) - return; - - if (!Lambda->hasExplicitParameters() && !Lambda->isGenericLambda()) - return; - if (Lambda->getCallOperator()->getNumParams() != 0) - return; - - if (Lambda->isGenericLambda() && !getLangOpts().CPlusPlus20) + if (Lambda->getBeginLoc().isMacroID()) return; const LangOptions &LangOpts = getLangOpts(); - SourceLocation ScanFrom; - if (Lambda->isGenericLambda()) { - TemplateParameterList *TPL = Lambda->getTemplateParameterList(); - ScanFrom = Lexer::getLocForEndOfToken(TPL->getRAngleLoc(), 0, - *Result.SourceManager, LangOpts); - } else { - ScanFrom = Lexer::getLocForEndOfToken(Lambda->getIntroducerRange().getEnd(), - 0, *Result.SourceManager, LangOpts); - } + const SourceLocation ScanFrom = + Lambda->isGenericLambda() + ? Lexer::getLocForEndOfToken( + Lambda->getTemplateParameterList()->getRAngleLoc(), 0, + *Result.SourceManager, LangOpts) + : Lexer::getLocForEndOfToken( + Lambda->getIntroducerRange().getEnd(), 0, + *Result.SourceManager, LangOpts); Token Tok; if (Lexer::getRawToken(ScanFrom, Tok, *Result.SourceManager, LangOpts, @@ -53,8 +66,8 @@ void RedundantLambdaParenthesesCheck::check( if (Tok.isNot(tok::l_paren)) return; - SourceLocation LParenLoc = Tok.getLocation(); - SourceLocation RParenLoc = Lexer::findLocationAfterToken( + const SourceLocation LParenLoc = Tok.getLocation(); + const SourceLocation RParenLoc = Lexer::findLocationAfterToken( LParenLoc, tok::r_paren, *Result.SourceManager, LangOpts, /*SkipTrailingWhitespaceAndNewLine=*/false); @@ -78,11 +91,11 @@ void RedundantLambdaParenthesesCheck::check( return; } - CharSourceRange ParenRange = + const CharSourceRange ParenRange = CharSourceRange::getCharRange(LParenLoc, RParenLoc); diag(LParenLoc, "redundant empty parameter list in lambda expression") << FixItHint::CreateRemoval(ParenRange); } -} // namespace clang::tidy::readability +} // namespace clang::tidy::readability \ No newline at end of file diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h index 3437d703da1f4..0dfce17ccf13e 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h @@ -22,6 +22,11 @@ class RedundantLambdaParenthesesCheck : public ClangTidyCheck { public: RedundantLambdaParenthesesCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} + + std::optional<TraversalKind> getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } + void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { >From 8e51535597355e3967f413e38ecd66d8952be745 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Sat, 4 Apr 2026 19:17:13 +0300 Subject: [PATCH 06/13] Add newline to the end of the file --- .../clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp index 9241352e09cf4..938ca06226353 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp @@ -98,4 +98,4 @@ void RedundantLambdaParenthesesCheck::check( << FixItHint::CreateRemoval(ParenRange); } -} // namespace clang::tidy::readability \ No newline at end of file +} // namespace clang::tidy::readability >From 61fda54dc25d59472c7d23dd91045f6b8c4e7e37 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Sat, 4 Apr 2026 19:42:04 +0300 Subject: [PATCH 07/13] [clang-tidy] Fix clang-format issues --- .../RedundantLambdaParenthesesCheck.cpp | 16 +++++++--------- .../RedundantLambdaParenthesesCheck.h | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp index 938ca06226353..45f861a5e21d6 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp @@ -32,18 +32,17 @@ AST_MATCHER(clang::LambdaExpr, isGenericLambdaInCxx20OrLater) { namespace clang::tidy::readability { void RedundantLambdaParenthesesCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher( - lambdaExpr(hasExplicitOrGenericParameters(), hasNoParameters(), - isGenericLambdaInCxx20OrLater()) - .bind("lambda"), - this); + Finder->addMatcher(lambdaExpr(hasExplicitOrGenericParameters(), + hasNoParameters(), + isGenericLambdaInCxx20OrLater()) + .bind("lambda"), + this); } void RedundantLambdaParenthesesCheck::check( const MatchFinder::MatchResult &Result) { const auto *Lambda = Result.Nodes.getNodeAs<LambdaExpr>("lambda"); - if (Lambda->getBeginLoc().isMacroID()) return; @@ -54,9 +53,8 @@ void RedundantLambdaParenthesesCheck::check( ? Lexer::getLocForEndOfToken( Lambda->getTemplateParameterList()->getRAngleLoc(), 0, *Result.SourceManager, LangOpts) - : Lexer::getLocForEndOfToken( - Lambda->getIntroducerRange().getEnd(), 0, - *Result.SourceManager, LangOpts); + : Lexer::getLocForEndOfToken(Lambda->getIntroducerRange().getEnd(), 0, + *Result.SourceManager, LangOpts); Token Tok; if (Lexer::getRawToken(ScanFrom, Tok, *Result.SourceManager, LangOpts, diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h index 0dfce17ccf13e..2f2a716de70cf 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.h @@ -22,7 +22,7 @@ class RedundantLambdaParenthesesCheck : public ClangTidyCheck { public: RedundantLambdaParenthesesCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} - + std::optional<TraversalKind> getCheckTraversalKind() const override { return TK_IgnoreUnlessSpelledInSource; } >From 8a0f91c3b01fe50ed27a94f8bceeae92e1b3ee41 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Sat, 4 Apr 2026 23:59:53 +0300 Subject: [PATCH 08/13] [clang-tidy] Address review: use FunctionTypeLoc, move matchers, remove unnecessary regex --- .../RedundantLambdaParenthesesCheck.cpp | 36 +++++-------------- .../redundant-lambda-parentheses-cxx20.cpp | 4 +-- .../redundant-lambda-parentheses-cxx23.cpp | 14 ++++---- .../redundant-lambda-parentheses.cpp | 8 ++--- 4 files changed, 22 insertions(+), 40 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp index 45f861a5e21d6..80b5316c77702 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp @@ -7,30 +7,29 @@ //===----------------------------------------------------------------------===// #include "RedundantLambdaParenthesesCheck.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" using namespace clang::ast_matchers; +namespace clang::tidy::readability { + namespace { -AST_MATCHER(clang::LambdaExpr, hasNoParameters) { +AST_MATCHER(LambdaExpr, hasNoParameters) { return Node.getCallOperator()->getNumParams() == 0; } -AST_MATCHER(clang::LambdaExpr, hasExplicitOrGenericParameters) { +AST_MATCHER(LambdaExpr, hasExplicitOrGenericParameters) { return Node.hasExplicitParameters() || Node.isGenericLambda(); } -AST_MATCHER(clang::LambdaExpr, isGenericLambdaInCxx20OrLater) { +AST_MATCHER(LambdaExpr, isGenericLambdaInCxx20OrLater) { return !Node.isGenericLambda() || Finder->getASTContext().getLangOpts().CPlusPlus20; } } // namespace -namespace clang::tidy::readability { - void RedundantLambdaParenthesesCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(lambdaExpr(hasExplicitOrGenericParameters(), hasNoParameters(), @@ -48,26 +47,9 @@ void RedundantLambdaParenthesesCheck::check( const LangOptions &LangOpts = getLangOpts(); - const SourceLocation ScanFrom = - Lambda->isGenericLambda() - ? Lexer::getLocForEndOfToken( - Lambda->getTemplateParameterList()->getRAngleLoc(), 0, - *Result.SourceManager, LangOpts) - : Lexer::getLocForEndOfToken(Lambda->getIntroducerRange().getEnd(), 0, - *Result.SourceManager, LangOpts); - - Token Tok; - if (Lexer::getRawToken(ScanFrom, Tok, *Result.SourceManager, LangOpts, - /*IgnoreWhiteSpace=*/true)) - return; - - if (Tok.isNot(tok::l_paren)) - return; - - const SourceLocation LParenLoc = Tok.getLocation(); - const SourceLocation RParenLoc = Lexer::findLocationAfterToken( - LParenLoc, tok::r_paren, *Result.SourceManager, LangOpts, - /*SkipTrailingWhitespaceAndNewLine=*/false); + const auto FTL = Lambda->getCallOperator()->getFunctionTypeLoc(); + const SourceLocation LParenLoc = FTL.getLParenLoc(); + const SourceLocation RParenLoc = FTL.getRParenLoc(); if (LParenLoc.isInvalid() || RParenLoc.isInvalid()) return; @@ -90,7 +72,7 @@ void RedundantLambdaParenthesesCheck::check( } const CharSourceRange ParenRange = - CharSourceRange::getCharRange(LParenLoc, RParenLoc); + CharSourceRange::getCharRange(LParenLoc, Lexer::getLocForEndOfToken(RParenLoc, 0, *Result.SourceManager, LangOpts)); diag(LParenLoc, "redundant empty parameter list in lambda expression") << FixItHint::CreateRemoval(ParenRange); diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp index e28da89a8ad6f..0921741fdb718 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp @@ -4,11 +4,11 @@ int main() { // Generic lambdas - should warn in C++20 and later auto a = []<class T>() { return sizeof(T); }; // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto a = []<class T> { return sizeof(T); };{{$}} + // CHECK-FIXES: auto a = []<class T> { return sizeof(T); }; auto b = []<class T>() requires true { return sizeof(T); }; // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto b = []<class T> requires true { return sizeof(T); };{{$}} + // CHECK-FIXES: auto b = []<class T> requires true { return sizeof(T); }; // Should NOT warn - has parameters auto c = []<class T>(T x) { return x; }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp index 21a6e90508530..4428d0cb0d257 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp @@ -4,32 +4,32 @@ int main() { // Basic cases - should warn auto a = []() { return 42; }; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto a = [] { return 42; };{{$}} + // CHECK-FIXES: auto a = [] { return 42; }; // Specifier cases - should also warn in C++23 auto b = []() mutable {}; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto b = [] mutable {};{{$}} + // CHECK-FIXES: auto b = [] mutable {}; auto c = []() noexcept {}; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto c = [] noexcept {};{{$}} + // CHECK-FIXES: auto c = [] noexcept {}; auto d = []() -> int { return 0; }; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto d = [] -> int { return 0; };{{$}} + // CHECK-FIXES: auto d = [] -> int { return 0; }; auto e = []() mutable noexcept {}; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto e = [] mutable noexcept {};{{$}} + // CHECK-FIXES: auto e = [] mutable noexcept {}; auto f = []() constexpr { return 42; }; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto f = [] constexpr { return 42; };{{$}} + // CHECK-FIXES: auto f = [] constexpr { return 42; }; auto g = []() consteval { return 42; }; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto g = [] consteval { return 42; };{{$}} + // CHECK-FIXES: auto g = [] consteval { return 42; }; // Should NOT warn - has parameters auto h = [](int x) { return x; }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp index 2e7fe14f5da29..02f575edf6ec8 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp @@ -4,22 +4,22 @@ int main() { // Basic cases - should warn auto a = []() { return 42; }; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto a = [] { return 42; };{{$}} + // CHECK-FIXES: auto a = [] { return 42; }; auto b = [x = 1]() { return x; }; // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto b = [x = 1] { return x; };{{$}} + // CHECK-FIXES: auto b = [x = 1] { return x; }; // Lambda with no captures auto c = []() {}; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto c = [] {};{{$}} + // CHECK-FIXES: auto c = [] {}; // Lambda inside a function call auto v = 1; auto call = [&v]() { return v; }; // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: {{^}} auto call = [&v] { return v; };{{$}} + // CHECK-FIXES: auto call = [&v] { return v; }; // Should NOT warn - has parameters auto d = [](int x) { return x; }; >From 1891ec1ddcdaf95b5269b2c8d0b2ce12d1895bf3 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Sun, 5 Apr 2026 00:10:16 +0300 Subject: [PATCH 09/13] [clang-tidy] Fix clang-format line wrapping --- .../readability/RedundantLambdaParenthesesCheck.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp index 80b5316c77702..2b1cb18cd376b 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp @@ -71,8 +71,9 @@ void RedundantLambdaParenthesesCheck::check( return; } - const CharSourceRange ParenRange = - CharSourceRange::getCharRange(LParenLoc, Lexer::getLocForEndOfToken(RParenLoc, 0, *Result.SourceManager, LangOpts)); + const CharSourceRange ParenRange = CharSourceRange::getCharRange( + LParenLoc, Lexer::getLocForEndOfToken(RParenLoc, 0, *Result.SourceManager, + LangOpts)); diag(LParenLoc, "redundant empty parameter list in lambda expression") << FixItHint::CreateRemoval(ParenRange); >From 8fffd05bd0cde5f4f35969d638e94518d1432e58 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Mon, 6 Apr 2026 01:53:08 +0300 Subject: [PATCH 10/13] [clang-tidy] Address review: use or-later standards and add guarded specifier cases --- .../redundant-lambda-parentheses-cxx20.cpp | 10 ++++++---- .../readability/redundant-lambda-parentheses.cpp | 16 ++++++++-------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp index 0921741fdb718..433a19b681848 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp @@ -1,19 +1,21 @@ -// RUN: %check_clang_tidy -std=c++20 %s readability-redundant-lambda-parentheses %t +// RUN: %check_clang_tidy -std=c++20-or-later %s readability-redundant-lambda-parentheses %t int main() { // Generic lambdas - should warn in C++20 and later auto a = []<class T>() { return sizeof(T); }; // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto a = []<class T> { return sizeof(T); }; + // CHECK-FIXES: auto a = []<class T> { return sizeof(T); }; auto b = []<class T>() requires true { return sizeof(T); }; // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto b = []<class T> requires true { return sizeof(T); }; + // CHECK-FIXES: auto b = []<class T> requires true { return sizeof(T); }; // Should NOT warn - has parameters auto c = []<class T>(T x) { return x; }; - // Should NOT warn - has specifiers + // Should NOT warn under C++20 - has specifiers (only valid to remove in C++23+) +#if __cplusplus < 202302L auto d = []<class T>() mutable { return sizeof(T); }; auto e = []<class T>() noexcept { return sizeof(T); }; +#endif } diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp index 02f575edf6ec8..b5565a5a428fb 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp @@ -1,35 +1,35 @@ -// RUN: %check_clang_tidy -std=c++17 %s readability-redundant-lambda-parentheses %t +// RUN: %check_clang_tidy -std=c++17-or-later %s readability-redundant-lambda-parentheses %t int main() { // Basic cases - should warn auto a = []() { return 42; }; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto a = [] { return 42; }; + // CHECK-FIXES: auto a = [] { return 42; }; auto b = [x = 1]() { return x; }; // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto b = [x = 1] { return x; }; + // CHECK-FIXES: auto b = [x = 1] { return x; }; - // Lambda with no captures auto c = []() {}; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto c = [] {}; + // CHECK-FIXES: auto c = [] {}; - // Lambda inside a function call auto v = 1; auto call = [&v]() { return v; }; // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto call = [&v] { return v; }; + // CHECK-FIXES: auto call = [&v] { return v; }; // Should NOT warn - has parameters auto d = [](int x) { return x; }; auto e = [](int x, int y) { return x + y; }; - // Should NOT warn - has specifiers, needs C++23 + // Should NOT warn under C++17/20 - has specifiers (only valid to remove in C++23+) +#if __cplusplus < 202302L auto f = []() mutable {}; auto g = []() noexcept {}; auto h = []() -> int { return 0; }; auto i = []() constexpr { return 42; }; +#endif // Should NOT warn - macro #define LAMBDA []() { return 42; } >From a2626b47f1feb20265d8ef2936c507a09ea1abe8 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Mon, 6 Apr 2026 15:29:47 +0300 Subject: [PATCH 11/13] [clang-tidy] Address review: merge test files into single file with check-suffixes --- .../RedundantLambdaParenthesesCheck.cpp | 28 +++------- .../redundant-lambda-parentheses-cxx20.cpp | 21 ------- .../redundant-lambda-parentheses-cxx23.cpp | 41 -------------- .../redundant-lambda-parentheses.cpp | 56 +++++++++++++++---- 4 files changed, 53 insertions(+), 93 deletions(-) delete mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp delete mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp index 2b1cb18cd376b..7ed77276e2043 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp @@ -15,27 +15,17 @@ namespace clang::tidy::readability { namespace { -AST_MATCHER(LambdaExpr, hasNoParameters) { - return Node.getCallOperator()->getNumParams() == 0; -} - -AST_MATCHER(LambdaExpr, hasExplicitOrGenericParameters) { - return Node.hasExplicitParameters() || Node.isGenericLambda(); -} - -AST_MATCHER(LambdaExpr, isGenericLambdaInCxx20OrLater) { - return !Node.isGenericLambda() || - Finder->getASTContext().getLangOpts().CPlusPlus20; +AST_MATCHER(LambdaExpr, hasRedundantParens) { + return (Node.hasExplicitParameters() || Node.isGenericLambda()) && + Node.getCallOperator()->getNumParams() == 0 && + (!Node.isGenericLambda() || + Finder->getASTContext().getLangOpts().CPlusPlus20); } } // namespace void RedundantLambdaParenthesesCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(lambdaExpr(hasExplicitOrGenericParameters(), - hasNoParameters(), - isGenericLambdaInCxx20OrLater()) - .bind("lambda"), - this); + Finder->addMatcher(lambdaExpr(hasRedundantParens()).bind("lambda"), this); } void RedundantLambdaParenthesesCheck::check( @@ -71,12 +61,8 @@ void RedundantLambdaParenthesesCheck::check( return; } - const CharSourceRange ParenRange = CharSourceRange::getCharRange( - LParenLoc, Lexer::getLocForEndOfToken(RParenLoc, 0, *Result.SourceManager, - LangOpts)); - diag(LParenLoc, "redundant empty parameter list in lambda expression") - << FixItHint::CreateRemoval(ParenRange); + << FixItHint::CreateRemoval({LParenLoc, RParenLoc}); } } // namespace clang::tidy::readability diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp deleted file mode 100644 index 433a19b681848..0000000000000 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx20.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %check_clang_tidy -std=c++20-or-later %s readability-redundant-lambda-parentheses %t - -int main() { - // Generic lambdas - should warn in C++20 and later - auto a = []<class T>() { return sizeof(T); }; - // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto a = []<class T> { return sizeof(T); }; - - auto b = []<class T>() requires true { return sizeof(T); }; - // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto b = []<class T> requires true { return sizeof(T); }; - - // Should NOT warn - has parameters - auto c = []<class T>(T x) { return x; }; - - // Should NOT warn under C++20 - has specifiers (only valid to remove in C++23+) -#if __cplusplus < 202302L - auto d = []<class T>() mutable { return sizeof(T); }; - auto e = []<class T>() noexcept { return sizeof(T); }; -#endif -} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp deleted file mode 100644 index 4428d0cb0d257..0000000000000 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses-cxx23.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// RUN: %check_clang_tidy -std=c++23 %s readability-redundant-lambda-parentheses %t - -int main() { - // Basic cases - should warn - auto a = []() { return 42; }; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto a = [] { return 42; }; - - // Specifier cases - should also warn in C++23 - auto b = []() mutable {}; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto b = [] mutable {}; - - auto c = []() noexcept {}; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto c = [] noexcept {}; - - auto d = []() -> int { return 0; }; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto d = [] -> int { return 0; }; - - auto e = []() mutable noexcept {}; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto e = [] mutable noexcept {}; - - auto f = []() constexpr { return 42; }; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto f = [] constexpr { return 42; }; - - auto g = []() consteval { return 42; }; - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES: auto g = [] consteval { return 42; }; - - // Should NOT warn - has parameters - auto h = [](int x) { return x; }; - - // Should NOT warn - macro -#define LAMBDA []() { return 42; } - auto i = LAMBDA; -#undef LAMBDA -} diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp index b5565a5a428fb..a823eca8113ca 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp @@ -1,7 +1,9 @@ -// RUN: %check_clang_tidy -std=c++17-or-later %s readability-redundant-lambda-parentheses %t +// RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s readability-redundant-lambda-parentheses %t +// RUN: %check_clang_tidy -std=c++20 -check-suffixes=,CXX20 %s readability-redundant-lambda-parentheses %t +// RUN: %check_clang_tidy -std=c++23-or-later -check-suffixes=,CXX20,CXX23 %s readability-redundant-lambda-parentheses %t int main() { - // Basic cases - should warn + // Basic cases - warn in all standards auto a = []() { return 42; }; // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] // CHECK-FIXES: auto a = [] { return 42; }; @@ -23,16 +25,50 @@ int main() { auto d = [](int x) { return x; }; auto e = [](int x, int y) { return x + y; }; - // Should NOT warn under C++17/20 - has specifiers (only valid to remove in C++23+) -#if __cplusplus < 202302L - auto f = []() mutable {}; - auto g = []() noexcept {}; - auto h = []() -> int { return 0; }; - auto i = []() constexpr { return 42; }; -#endif - // Should NOT warn - macro #define LAMBDA []() { return 42; } auto k = LAMBDA; #undef LAMBDA + + // Generic lambda - warns in C++20 and later +#if __cplusplus >= 202002L + auto f = []<class T>() { return sizeof(T); }; + // CHECK-MESSAGES-CXX20: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES-CXX20: auto f = []<class T> { return sizeof(T); }; + + auto g = []<class T>() requires true { return sizeof(T); }; + // CHECK-MESSAGES-CXX20: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES-CXX20: auto g = []<class T> requires true { return sizeof(T); }; + + // Should NOT warn - has parameters + auto h = []<class T>(T x) { return x; }; +#endif + + // Specifier cases - warn only in C++23, valid syntax in all standards + auto i = []() mutable {}; + // CHECK-MESSAGES-CXX23: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES-CXX23: auto i = [] mutable {}; + + auto j = []() noexcept {}; + // CHECK-MESSAGES-CXX23: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES-CXX23: auto j = [] noexcept {}; + + auto l = []() -> int { return 0; }; + // CHECK-MESSAGES-CXX23: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES-CXX23: auto l = [] -> int { return 0; }; + + auto m = []() mutable noexcept {}; + // CHECK-MESSAGES-CXX23: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES-CXX23: auto m = [] mutable noexcept {}; + + auto n = []() constexpr { return 42; }; + // CHECK-MESSAGES-CXX23: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES-CXX23: auto n = [] constexpr { return 42; }; + + // consteval only valid in C++20+ +#if __cplusplus >= 202002L + auto o = []() consteval { return 42; }; + // CHECK-MESSAGES-CXX23: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES-CXX23: auto o = [] consteval { return 42; }; +#endif } >From 8f246ffd80382a5e5580b7c262a46e6b58633f4b Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Tue, 7 Apr 2026 22:03:28 +0300 Subject: [PATCH 12/13] [clang-tidy] Address review: simplify matcher, add attribute and requires guards, update tests --- .../RedundantLambdaParenthesesCheck.cpp | 23 +++++++++++-------- .../redundant-lambda-parentheses.cpp | 20 +++++++++++++--- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp index 7ed77276e2043..80eb0e5a7c091 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantLambdaParenthesesCheck.cpp @@ -16,10 +16,8 @@ namespace clang::tidy::readability { namespace { AST_MATCHER(LambdaExpr, hasRedundantParens) { - return (Node.hasExplicitParameters() || Node.isGenericLambda()) && - Node.getCallOperator()->getNumParams() == 0 && - (!Node.isGenericLambda() || - Finder->getASTContext().getLangOpts().CPlusPlus20); + return Node.hasExplicitParameters() && + Node.getCallOperator()->getNumParams() == 0; } } // namespace @@ -44,13 +42,18 @@ void RedundantLambdaParenthesesCheck::check( if (LParenLoc.isInvalid() || RParenLoc.isInvalid()) return; + std::optional<Token> NextTok = + Lexer::findNextToken(RParenLoc, *Result.SourceManager, LangOpts); + + // Attributes after '()' have different semantics depending on position. + if (NextTok && NextTok->is(tok::l_square)) + return; + + // requires clause after '()' means parens cannot be removed. + if (Lambda->getCallOperator()->getTrailingRequiresClause()) + return; + if (!LangOpts.CPlusPlus23) { - std::optional<Token> RParen = - Lexer::findNextToken(LParenLoc, *Result.SourceManager, LangOpts); - if (!RParen || RParen->isNot(tok::r_paren)) - return; - std::optional<Token> NextTok = Lexer::findNextToken( - RParen->getLocation(), *Result.SourceManager, LangOpts); if (NextTok && NextTok->is(tok::raw_identifier)) { StringRef Id = NextTok->getRawIdentifier(); if (Id == "constexpr" || Id == "consteval" || Id == "mutable" || diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp index a823eca8113ca..e7919d6e4d29c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp @@ -2,6 +2,21 @@ // RUN: %check_clang_tidy -std=c++20 -check-suffixes=,CXX20 %s readability-redundant-lambda-parentheses %t // RUN: %check_clang_tidy -std=c++23-or-later -check-suffixes=,CXX20,CXX23 %s readability-redundant-lambda-parentheses %t +#if __cplusplus >= 202002L +template <bool B> +void testRequires() { + // Should NOT warn - requires clause after parens + auto f1 = []() requires B {}; + auto f2 = []() noexcept requires B {}; + auto f3 = []<typename T>() requires B {}; + + // Should warn - requires clause is before parens, parens are removable + auto f4 = []<typename T> requires B () {}; + // CHECK-MESSAGES-CXX20: :[[@LINE-1]]:39: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES-CXX20: auto f4 = []<typename T> requires B {}; +} +#endif + int main() { // Basic cases - warn in all standards auto a = []() { return 42; }; @@ -36,9 +51,8 @@ int main() { // CHECK-MESSAGES-CXX20: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] // CHECK-FIXES-CXX20: auto f = []<class T> { return sizeof(T); }; - auto g = []<class T>() requires true { return sizeof(T); }; - // CHECK-MESSAGES-CXX20: :[[@LINE-1]]:23: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] - // CHECK-FIXES-CXX20: auto g = []<class T> requires true { return sizeof(T); }; + // Should NOT warn - requires clause after parens + auto g = []<class T>() requires (sizeof(T) > 0) {}; // Should NOT warn - has parameters auto h = []<class T>(T x) { return x; }; >From b0a4c3e544b67802047a62a12ed4e6bba3f3ade6 Mon Sep 17 00:00:00 2001 From: OmarAzizi <[email protected]> Date: Wed, 8 Apr 2026 02:08:10 +0300 Subject: [PATCH 13/13] [clang-tidy] Address review: add tests with empty attributes --- .../checkers/readability/redundant-lambda-parentheses.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp index e7919d6e4d29c..673e7a79c4874 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/redundant-lambda-parentheses.cpp @@ -85,4 +85,12 @@ int main() { // CHECK-MESSAGES-CXX23: :[[@LINE-1]]:14: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] // CHECK-FIXES-CXX23: auto o = [] consteval { return 42; }; #endif + + // Should NOT warn - attribute after parens + auto p = []() [[]] {}; + + // Should warn - attribute before parens + auto q = [] [[]] () {}; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant empty parameter list in lambda expression [readability-redundant-lambda-parentheses] + // CHECK-FIXES: auto q = [] {{\[\[}}{{\]\]}} {}; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
