https://github.com/mugiwaraluffy56 updated https://github.com/llvm/llvm-project/pull/178965
>From a573cdfdf77fb1687d0a6911f2102aa54808010a Mon Sep 17 00:00:00 2001 From: mugiwaraluffy56 <[email protected]> Date: Sat, 31 Jan 2026 02:46:07 +0530 Subject: [PATCH] [clang-tidy] Add IgnoreAboveThreshold option to readability-function-cognitive-complexity This adds a new option IgnoreAboveThreshold that allows users to skip functions with cognitive complexity at or above a certain threshold. This is useful for ignoring "hopelessly" complex functions that would be too costly to refactor. When set to 0 (the default), this option is disabled. Fixes #178959 --- .../FunctionCognitiveComplexityCheck.cpp | 14 +++++++++++- .../FunctionCognitiveComplexityCheck.h | 4 ++++ clang-tools-extra/docs/ReleaseNotes.rst | 4 ++++ .../function-cognitive-complexity.rst | 6 +++++ .../function-cognitive-complexity-flags.cpp | 8 +++++++ ...tion-cognitive-complexity-wrong-config.cpp | 22 +++++++++++++++++++ 6 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/function-cognitive-complexity-wrong-config.cpp diff --git a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp index 1d8c4f8b58d8f..431d7fe972f59 100644 --- a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp @@ -474,12 +474,20 @@ FunctionCognitiveComplexityCheck::FunctionCognitiveComplexityCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), Threshold(Options.get("Threshold", CognitiveComplexity::DefaultLimit)), + IgnoreAboveThreshold(Options.get("IgnoreAboveThreshold", std::nullopt)), DescribeBasicIncrements(Options.get("DescribeBasicIncrements", true)), - IgnoreMacros(Options.get("IgnoreMacros", false)) {} + IgnoreMacros(Options.get("IgnoreMacros", false)) { + if (IgnoreAboveThreshold && *IgnoreAboveThreshold < Threshold) + configurationDiag("'IgnoreAboveThreshold' option value '%0' is less than " + "'Threshold' option value '%1'; the option will be " + "ignored") + << *IgnoreAboveThreshold << Threshold; +} void FunctionCognitiveComplexityCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "Threshold", Threshold); + Options.store(Opts, "IgnoreAboveThreshold", IgnoreAboveThreshold); Options.store(Opts, "DescribeBasicIncrements", DescribeBasicIncrements); Options.store(Opts, "IgnoreMacros", IgnoreMacros); } @@ -514,6 +522,10 @@ void FunctionCognitiveComplexityCheck::check( if (Visitor.CC.Total <= Threshold) return; + // Skip functions that are "hopelessly" complex. + if (IgnoreAboveThreshold && Visitor.CC.Total >= *IgnoreAboveThreshold) + return; + if (TheDecl) diag(Loc, "function %0 has cognitive complexity of %1 (threshold %2)") << TheDecl << Visitor.CC.Total << Threshold; diff --git a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.h b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.h index 046c6e162af88..82c54d3784fe2 100644 --- a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.h +++ b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.h @@ -19,6 +19,9 @@ namespace clang::tidy::readability { /// /// * `Threshold` - flag functions with Cognitive Complexity exceeding /// this number. The default is `25`. +/// * `IgnoreAboveThreshold` - do not flag functions with Cognitive Complexity +/// at or above this number. This can be used to skip "hopelessly" complex +/// functions. The default is none (option disabled). /// * `DescribeBasicIncrements`- if set to `true`, then for each function /// exceeding the complexity threshold the check will issue additional /// diagnostics on every piece of code (loop, `if` statement, etc.) which @@ -42,6 +45,7 @@ class FunctionCognitiveComplexityCheck : public ClangTidyCheck { private: const unsigned Threshold; + const std::optional<unsigned> IgnoreAboveThreshold; const bool DescribeBasicIncrements; const bool IgnoreMacros; }; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index ea80502735ede..4af4b46dc8c94 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -193,6 +193,10 @@ Changes in existing checks now uses separate note diagnostics for each uninitialized enumerator, making it easier to see which specific enumerators need explicit initialization. +- Improved :doc:`readability-function-cognitive-complexity + <clang-tidy/checks/readability/function-cognitive-complexity>` check by adding + an `IgnoreAboveThreshold` option to skip overly complex functions. + - Improved :doc:`readability-non-const-parameter <clang-tidy/checks/readability/non-const-parameter>` check by avoiding false positives on parameters used in dependent expressions. diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/function-cognitive-complexity.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/function-cognitive-complexity.rst index 430006e68ceb4..07839c3a5e28d 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/function-cognitive-complexity.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/function-cognitive-complexity.rst @@ -17,6 +17,12 @@ Options Flag functions with Cognitive Complexity exceeding this number. The default is `25`. +.. option:: IgnoreAboveThreshold + + Do not flag functions with Cognitive Complexity at or above this number. + This can be used to skip "hopelessly" complex functions that would be too + costly to refactor. The default is none (option disabled). + .. option:: DescribeBasicIncrements If set to `true`, then for each function exceeding the complexity threshold diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/function-cognitive-complexity-flags.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/function-cognitive-complexity-flags.cpp index 196f3181141f9..af74a9ea626c6 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/function-cognitive-complexity-flags.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/function-cognitive-complexity-flags.cpp @@ -11,10 +11,16 @@ // RUN: {readability-function-cognitive-complexity.Threshold: 0, \ // RUN: readability-function-cognitive-complexity.IgnoreMacros: "true", \ // RUN: readability-function-cognitive-complexity.DescribeBasicIncrements: "false"}}' +// RUN: %check_clang_tidy -check-suffix=IGNORE-ABOVE %s readability-function-cognitive-complexity %t -- \ +// RUN: -config='{CheckOptions: \ +// RUN: {readability-function-cognitive-complexity.Threshold: 0, \ +// RUN: readability-function-cognitive-complexity.IgnoreAboveThreshold: 10, \ +// RUN: readability-function-cognitive-complexity.DescribeBasicIncrements: "false"}}' void func_of_complexity_4() { // CHECK-NOTES: :[[@LINE-1]]:6: warning: function 'func_of_complexity_4' has cognitive complexity of 4 (threshold 0) [readability-function-cognitive-complexity] // CHECK-NOTES-IGNORE-MACROS: :[[@LINE-2]]:6: warning: function 'func_of_complexity_4' has cognitive complexity of 4 (threshold 0) [readability-function-cognitive-complexity] + // CHECK-NOTES-IGNORE-ABOVE: :[[@LINE-3]]:6: warning: function 'func_of_complexity_4' has cognitive complexity of 4 (threshold 0) [readability-function-cognitive-complexity] if (1) { if (1) { } @@ -55,6 +61,7 @@ void function_with_macro() { void func_macro_1() { // CHECK-NOTES: :[[@LINE-1]]:6: warning: function 'func_macro_1' has cognitive complexity of 2 (threshold 0) [readability-function-cognitive-complexity] // CHECK-NOTES-IGNORE-MACROS: :[[@LINE-2]]:6: warning: function 'func_macro_1' has cognitive complexity of 1 (threshold 0) [readability-function-cognitive-complexity] + // CHECK-NOTES-IGNORE-ABOVE: :[[@LINE-3]]:6: warning: function 'func_macro_1' has cognitive complexity of 2 (threshold 0) [readability-function-cognitive-complexity] if (1) { } @@ -64,6 +71,7 @@ void func_macro_1() { void func_macro_2() { // CHECK-NOTES: :[[@LINE-1]]:6: warning: function 'func_macro_2' has cognitive complexity of 4 (threshold 0) [readability-function-cognitive-complexity] // CHECK-NOTES-IGNORE-MACROS: :[[@LINE-2]]:6: warning: function 'func_macro_2' has cognitive complexity of 1 (threshold 0) [readability-function-cognitive-complexity] + // CHECK-NOTES-IGNORE-ABOVE: :[[@LINE-3]]:6: warning: function 'func_macro_2' has cognitive complexity of 4 (threshold 0) [readability-function-cognitive-complexity] if (1) { } diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/function-cognitive-complexity-wrong-config.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/function-cognitive-complexity-wrong-config.cpp new file mode 100644 index 0000000000000..82f603e0653c8 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/function-cognitive-complexity-wrong-config.cpp @@ -0,0 +1,22 @@ +// RUN: %check_clang_tidy %s readability-function-cognitive-complexity %t -- \ +// RUN: -config='{CheckOptions: { \ +// RUN: readability-function-cognitive-complexity.Threshold: 10, \ +// RUN: readability-function-cognitive-complexity.IgnoreAboveThreshold: 5, \ +// RUN: readability-function-cognitive-complexity.DescribeBasicIncrements: false \ +// RUN: }}' + +// CHECK-MESSAGES: warning: 'IgnoreAboveThreshold' option value '5' is less than 'Threshold' option value '10'; the option will be ignored [clang-tidy-config] + +// The IgnoreAboveThreshold option is ignored when it's less than Threshold, +// so this function with complexity 11 should still be flagged. +void func_of_complexity_11() { + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_of_complexity_11' has cognitive complexity of 11 (threshold 10) [readability-function-cognitive-complexity] + if (1) { + if (1) { + if (1) { + if (1) { + } + } + } + } +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
