From 5eaa50f1d5191ae74e0a1bbe60e8d1fcf36507e3 Mon Sep 17 00:00:00 2001 From: Simon Breidenbach Date: Wed, 29 Jul 2026 14:48:00 +0200 Subject: [PATCH 1/2] fix(braces): exempt C++20 templated lambdas from trailing-semicolon check A C++20 templated lambda like [](T&& t) { ... }; was falsely flagged with readability/braces 'You don't need a ; after a }'. The lambda exemption relied on the text before '(' ending in ']' (the capture), but a template parameter list sits between ']' and '(' so the prefix ends in '>' and the exemption missed it. Also recognize the ]<...> introducer. Fixes #385 --- CHANGELOG.rst | 1 + cpplint.py | 1 + cpplint_unittest.py | 17 +++++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4127d4e..bfe5f32 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,7 @@ TBA === * Fixed a whitespace/newline false positive for control conditions containing lambdas. (#410) +* Fixed a false positive where C++20 templated lambdas (``[](...)``) triggered the redundant trailing semicolon warning. (#385) 2.0.2 (2025-04-08) =========== diff --git a/cpplint.py b/cpplint.py index 07687d2..cacf69e 100755 --- a/cpplint.py +++ b/cpplint.py @@ -5186,6 +5186,7 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error): ) ) or (func and not re.search(r"\boperator\s*\[\s*\]", func.group(1))) + or re.search(r"\]\s*<.*>\s*$", line_prefix) or re.search(r"\b(?:struct|union)\s+alignas\s*$", line_prefix) or re.search(r"\bdecltype$", line_prefix) or re.search(r"\brequires.*$", line_prefix) diff --git a/cpplint_unittest.py b/cpplint_unittest.py index d568251..38cf6e7 100755 --- a/cpplint_unittest.py +++ b/cpplint_unittest.py @@ -3186,6 +3186,23 @@ def testLambda(self): # Avoid false positives with operator[] self.TestLint("table_to_children[&*table].push_back(dependent);", "") + # C++20 templated lambdas: [](...) must not trigger the redundant + # trailing semicolon check. Regression test for #385. + self.TestLint("auto x = [](T) {};", "") + self.TestLint("auto x = [&](T (&a)[N]) {};", "") + self.TestMultiLineLint( + "auto x = [](T t) {\n" + " return t;\n" + "};\n", + "", + ) + # A templated *function* (not a lambda) with a redundant trailing + # semicolon must still be flagged. + self.TestLint( + "template void f() {};", + "You don't need a ; after a } [readability/braces] [4]", + ) + def testBraceInitializerList(self): self.TestLint("MyStruct p = {1, 2};", "") self.TestLint("MyStruct p{1, 2};", "") From c6a64d4409fe1f1707b3fbc5b46606cee5628069 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 18:57:06 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cpplint_unittest.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cpplint_unittest.py b/cpplint_unittest.py index 38cf6e7..876c51b 100755 --- a/cpplint_unittest.py +++ b/cpplint_unittest.py @@ -3191,9 +3191,7 @@ def testLambda(self): self.TestLint("auto x = [](T) {};", "") self.TestLint("auto x = [&](T (&a)[N]) {};", "") self.TestMultiLineLint( - "auto x = [](T t) {\n" - " return t;\n" - "};\n", + "auto x = [](T t) {\n return t;\n};\n", "", ) # A templated *function* (not a lambda) with a redundant trailing