From bb0c5b3915fe68ca1c8438fdd8ffe29f161f0354 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Thu, 17 Apr 2025 15:56:28 -0400 Subject: [PATCH 1/3] fix(readability/casting): noexcept *functions --- cpplint.py | 6 +++--- cpplint_unittest.py | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cpplint.py b/cpplint.py index 128bb3c..db1ed9d 100755 --- a/cpplint.py +++ b/cpplint.py @@ -6820,10 +6820,10 @@ def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): if context.endswith((" operator++", " operator--", "::operator++", "::operator--")): return False - # A single unnamed argument for a function tends to look like old style cast. - # If we see those, don't issue warnings for deprecated casts. + # A single unnamed argument for a function tend to look like old style cast; + # so do function pointers. If we see those, don't issue warnings for deprecated casts. remainder = line[match.end(0) :] - if re.match(r"^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)", remainder): + if re.match(r"^\s*(?:;|(?:const|throw|final|override|noexcept)\b|[=>{),]|->)", remainder): return False # At this point, all that should be left is actual casts. diff --git a/cpplint_unittest.py b/cpplint_unittest.py index 7b39074..29e95cf 100755 --- a/cpplint_unittest.py +++ b/cpplint_unittest.py @@ -1107,6 +1107,7 @@ def testDeprecatedCast(self): self.TestLint("void Function(bool(FunctionPointerArg)()) {}", "") self.TestLint("typedef set SortedIdSet", "") self.TestLint("bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *t)) {}", "") + self.TestLint("void (*execute_)(operation_base*) noexcept(may_throw());", "") # The second parameter to a gMock method definition is a function signature # that often looks like a bad cast but should not picked up by lint. From a90a9715d56613c221a5b7dbe17859ed85fb6720 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Thu, 17 Apr 2025 15:58:06 -0400 Subject: [PATCH 2/3] fix typo --- cpplint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpplint.py b/cpplint.py index db1ed9d..94b555b 100755 --- a/cpplint.py +++ b/cpplint.py @@ -6820,7 +6820,7 @@ def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): if context.endswith((" operator++", " operator--", "::operator++", "::operator--")): return False - # A single unnamed argument for a function tend to look like old style cast; + # A single unnamed argument for a function tends to look like old style cast; # so do function pointers. If we see those, don't issue warnings for deprecated casts. remainder = line[match.end(0) :] if re.match(r"^\s*(?:;|(?:const|throw|final|override|noexcept)\b|[=>{),]|->)", remainder): From f44a09acf0a936fecda31f23cd6c049d63d48044 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Mon, 20 Jul 2026 22:14:23 -0400 Subject: [PATCH 3/3] alternative approach to exclude "cast"s that follow closing parenthesis without space it seems rare that a cast would directly follow a closing parenthesis and this excludes function pointers, avoiding the noexcept issue entirely without accidentally skipping the noexcept operator as well add unit test for noexcept operator true positive add TODO on refactoring CheckCStyleCast() --- cpplint.py | 9 +++++---- cpplint_unittest.py | 7 +++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/cpplint.py b/cpplint.py index 94b555b..8e547aa 100755 --- a/cpplint.py +++ b/cpplint.py @@ -6720,7 +6720,7 @@ def CheckCasts(filename, clean_lines, linenum, error): else: # Check pointer casts for other than string constants CheckCStyleCast( - filename, clean_lines, linenum, "reinterpret_cast", r"\((\w+\s?\*+\s?)\)", error + filename, clean_lines, linenum, "reinterpret_cast", r"(?{),]|->)", remainder): + if re.match(r"^\s*(?:;|(?:const|throw|final|override)\b|[=>{),]|->)", remainder): return False # At this point, all that should be left is actual casts. diff --git a/cpplint_unittest.py b/cpplint_unittest.py index 29e95cf..ee9c7b4 100755 --- a/cpplint_unittest.py +++ b/cpplint_unittest.py @@ -1050,18 +1050,21 @@ def testDeprecatedCast(self): "Use static_cast(...) instead" " [readability/casting] [4]", ) - self.TestLint( '(char *) "foo"', "Using C-style cast. Use const_cast(...) instead [readability/casting] [4]", ) - self.TestLint( "(int*)foo", "Using C-style cast. " "Use reinterpret_cast(...) instead" " [readability/casting] [4]", ) + self.TestLint( + "(Type**) noexcept(f())", + "Using C-style cast. " + "Use reinterpret_cast(...) instead [readability/casting] [4]", + ) # Checks for false positives... self.TestLint("int a = int();", "") # constructor