https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/131669
>From 2b4699fda6854235cf59c69d1bf511bd12799c43 Mon Sep 17 00:00:00 2001 From: Victor Baranov <bar.victor.2...@gmail.com> Date: Fri, 6 Jun 2025 18:46:11 +0300 Subject: [PATCH 1/2] [clang-tidy] count ctor-initializers as statements in function-size check --- .../readability/FunctionSizeCheck.cpp | 15 ++++- .../readability/FunctionSizeCheck.h | 2 + clang-tools-extra/docs/ReleaseNotes.rst | 5 ++ .../checks/readability/function-size.rst | 5 ++ .../function-size-no-member-init-as-stmts.cpp | 64 +++++++++++++++++++ .../checkers/readability/function-size.cpp | 50 +++++++++++++++ 6 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp diff --git a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp index 3313bcb39b7f3..8e3a2e306dbf7 100644 --- a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp @@ -108,6 +108,14 @@ class FunctionASTVisitor : public RecursiveASTVisitor<FunctionASTVisitor> { return true; } + bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { + if (CountMemberInitAsStmt) + ++Info.Statements; + + Base::TraverseConstructorInitializer(Init); + return true; + } + struct FunctionInfo { unsigned Lines = 0; unsigned Statements = 0; @@ -120,6 +128,7 @@ class FunctionASTVisitor : public RecursiveASTVisitor<FunctionASTVisitor> { llvm::BitVector TrackedParent; unsigned StructNesting = 0; unsigned CurrentNestingLevel = 0; + bool CountMemberInitAsStmt; }; } // namespace @@ -135,7 +144,9 @@ FunctionSizeCheck::FunctionSizeCheck(StringRef Name, ClangTidyContext *Context) NestingThreshold( Options.get("NestingThreshold", DefaultNestingThreshold)), VariableThreshold( - Options.get("VariableThreshold", DefaultVariableThreshold)) {} + Options.get("VariableThreshold", DefaultVariableThreshold)), + CountMemberInitAsStmt( + Options.get("CountMemberInitAsStmt", DefaultCountMemberInitAsStmt)) {} void FunctionSizeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "LineThreshold", LineThreshold); @@ -144,6 +155,7 @@ void FunctionSizeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "ParameterThreshold", ParameterThreshold); Options.store(Opts, "NestingThreshold", NestingThreshold); Options.store(Opts, "VariableThreshold", VariableThreshold); + Options.store(Opts, "CountMemberInitAsStmt", CountMemberInitAsStmt); } void FunctionSizeCheck::registerMatchers(MatchFinder *Finder) { @@ -160,6 +172,7 @@ void FunctionSizeCheck::check(const MatchFinder::MatchResult &Result) { FunctionASTVisitor Visitor; Visitor.Info.NestingThreshold = NestingThreshold.value_or(-1); + Visitor.CountMemberInitAsStmt = CountMemberInitAsStmt; Visitor.TraverseDecl(const_cast<FunctionDecl *>(Func)); auto &FI = Visitor.Info; diff --git a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h index 106c69ff07393..f668ab18fea52 100644 --- a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h +++ b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.h @@ -47,6 +47,7 @@ class FunctionSizeCheck : public ClangTidyCheck { const std::optional<unsigned> ParameterThreshold; const std::optional<unsigned> NestingThreshold; const std::optional<unsigned> VariableThreshold; + const bool CountMemberInitAsStmt; static constexpr std::optional<unsigned> DefaultLineThreshold = std::nullopt; static constexpr std::optional<unsigned> DefaultStatementThreshold = 800U; @@ -58,6 +59,7 @@ class FunctionSizeCheck : public ClangTidyCheck { std::nullopt; static constexpr std::optional<unsigned> DefaultVariableThreshold = std::nullopt; + static constexpr bool DefaultCountMemberInitAsStmt = true; }; } // namespace clang::tidy::readability diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index b7d0a223ce5bb..dc4a24b9d72e7 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -245,6 +245,11 @@ Changes in existing checks tolerating fix-it breaking compilation when functions is used as pointers to avoid matching usage of functions within the current compilation unit. +- Improved :doc:`readability-function-size + <clang-tidy/checks/readability/function-size>` check by adding new option + `CountMemberInitAsStmt` that allows counting class member initializers in + constructors as statements. + - Improved :doc:`readability-math-missing-parentheses <clang-tidy/checks/readability/math-missing-parentheses>` check by fixing false negatives where math expressions are the operand of assignment operators diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst index 133bd3e9c8cbe..253e7c483cb85 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/function-size.rst @@ -43,3 +43,8 @@ Options The default is `none` (ignore the number of variables). Please note that function parameters and variables declared in lambdas, GNU Statement Expressions, and nested class inline functions are not counted. + +.. option:: CountMemberInitAsStmt + + When `true`, count class member initializers in constructors as statements. + Default is `true`. diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp new file mode 100644 index 0000000000000..2301b4c7dee40 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp @@ -0,0 +1,64 @@ +// RUN: %check_clang_tidy %s readability-function-size %t -- \ +// RUN: -config='{CheckOptions: { \ +// RUN: readability-function-size.LineThreshold: 0, \ +// RUN: readability-function-size.StatementThreshold: 0, \ +// RUN: readability-function-size.BranchThreshold: 0, \ +// RUN: readability-function-size.ParameterThreshold: 5, \ +// RUN: readability-function-size.NestingThreshold: 2, \ +// RUN: readability-function-size.VariableThreshold: 1, \ +// RUN: readability-function-size.CountMemberInitAsStmt: false \ +// RUN: }}' + +// Bad formatting is intentional, don't run clang-format over the whole file! + +void foo1() { +} + +void foo2() {;} +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'foo2' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 1 statements (threshold 0) + +struct A { + A(int c, int d) : a(0), b(c) { ; } + int a; + int b; +}; +// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: function 'A' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-5]]:3: note: 1 statements (threshold 0) + +struct B { + B(int x, int y, int z) : a(x + y * z), b(), c_a(y, z) { + ; + } + int a; + int b; + A c_a; +}; +// CHECK-MESSAGES: :[[@LINE-7]]:3: warning: function 'B' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-8]]:3: note: 2 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-9]]:3: note: 1 statements (threshold 0) + +struct C : A, B { + // 0 statements + C() : A(0, 4), B(1, 2, 3) {} +}; + +template<typename T> +struct TemplateC { + // 0 statements + TemplateC() : a(3) {} + T a; +}; + +template<typename T> +struct TemplateD { + template<typename U> + TemplateD(U&& val) : member(val) { + ; + } + + T member; +}; +// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: function 'TemplateD<T>' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-7]]:3: note: 2 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-8]]:3: note: 1 statements (threshold 0) diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp index 45b2604b43d03..fb846ce01803a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp @@ -319,3 +319,53 @@ void variables_16() { // CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0) // CHECK-MESSAGES: :[[@LINE-6]]:6: note: 4 statements (threshold 0) // CHECK-MESSAGES: :[[@LINE-7]]:6: note: 2 variables (threshold 1) + +struct A { + A(int c, int d) : a(0), b(c) { ; } + int a; + int b; +}; +// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: function 'A' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-5]]:3: note: 3 statements (threshold 0) + +struct B { + B(int x, int y, int z) : a(x + y * z), b(), c_a(y, z) { + ; + } + int a; + int b; + A c_a; +}; +// CHECK-MESSAGES: :[[@LINE-7]]:3: warning: function 'B' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-8]]:3: note: 2 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-9]]:3: note: 4 statements (threshold 0) + +struct C : A, B { + C() : A(0, 4), B(1, 2, 3) {} +}; +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: function 'C' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-3]]:3: note: 2 statements (threshold 0) + +template<typename T> +struct TemplateC { + // 0 statements + TemplateC() : a(3) {} + T a; +}; +// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: function 'TemplateC<T>' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-4]]:3: note: 1 statements (threshold 0) + +template<typename T> +struct TemplateD { + template<typename U> + TemplateD(U&& val) : member(val) { + ; + } + + T member; +}; +// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: function 'TemplateD<T>' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-7]]:3: note: 2 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-8]]:3: note: 2 statements (threshold 0) + + >From d8cded05b795a65c54d9b2017f20febb7c6c5208 Mon Sep 17 00:00:00 2001 From: Victor Baranov <bar.victor.2...@gmail.com> Date: Fri, 6 Jun 2025 19:35:40 +0300 Subject: [PATCH 2/2] fix windows tests --- .../function-size-no-member-init-as-stmts.cpp | 9 +++++++++ .../clang-tidy/checkers/readability/function-size.cpp | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp index 2301b4c7dee40..d335988e5e033 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/function-size-no-member-init-as-stmts.cpp @@ -62,3 +62,12 @@ struct TemplateD { // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: function 'TemplateD<T>' exceeds recommended size/complexity thresholds [readability-function-size] // CHECK-MESSAGES: :[[@LINE-7]]:3: note: 2 lines including whitespace and comments (threshold 0) // CHECK-MESSAGES: :[[@LINE-8]]:3: note: 1 statements (threshold 0) + +void instantiate() { + TemplateC<int> c; + TemplateD<int> d(5); +} +// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'instantiate' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 2 statements (threshold 0) +// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 2 variables (threshold 1) diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp index fb846ce01803a..9364fa3077da6 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/function-size.cpp @@ -368,4 +368,11 @@ struct TemplateD { // CHECK-MESSAGES: :[[@LINE-7]]:3: note: 2 lines including whitespace and comments (threshold 0) // CHECK-MESSAGES: :[[@LINE-8]]:3: note: 2 statements (threshold 0) - +void instantiate() { + TemplateC<int> c; + TemplateD<int> d(5); +} +// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'instantiate' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 2 statements (threshold 0) +// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 2 variables (threshold 1) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits