llvm-project/clang-tools-extra/test/clang-tidy/checkers/readability-function-cognit...

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

96 lines
4.9 KiB
C++
Raw Normal View History

// RUN: %check_clang_tidy %s readability-function-cognitive-complexity %t -- \
// RUN: -config='{CheckOptions: \
// RUN: [{key: readability-function-cognitive-complexity.Threshold, \
// RUN: value: 0}, \
// RUN: {key: readability-function-cognitive-complexity.DescribeBasicIncrements, \
// RUN: value: "false"} ]}'
// RUN: %check_clang_tidy -check-suffix=THRESHOLD5 %s readability-function-cognitive-complexity %t -- \
// RUN: -config='{CheckOptions: \
// RUN: [{key: readability-function-cognitive-complexity.Threshold, \
// RUN: value: 5}, \
// RUN: {key: readability-function-cognitive-complexity.DescribeBasicIncrements, \
// RUN: value: "false"} ]}'
[clang-tidy] Add option to ignore macros in readability-function-cognitive-complexity check. (this was originally part of https://reviews.llvm.org/D96281 and has been split off into its own patch) If a macro is used within a function, the code inside the macro doesn't make the code less readable. Instead, for a reader a macro is more like a function that is called. Thus the code inside a macro shouldn't increase the complexity of the function in which it is called. Thus the flag 'IgnoreMacros' is added. If set to 'true' code inside macros isn't considered during analysis. This isn't perfect, as now the code of a macro isn't considered at all, even if it has a high cognitive complexity itself. It might be better if a macro is considered in the analysis like a function and gets its own cognitive complexity. Implementing such an analysis seems to be very complex (if possible at all with the given AST), so we give the user the option to either ignore macros completely or to let the expanded code count to the calling function's complexity. See the code example from vgeof (originally added as note in https://reviews.llvm.org/D96281) bool doStuff(myClass* objectPtr){ if(objectPtr == nullptr){ LOG_WARNING("empty object"); return false; } if(objectPtr->getAttribute() == nullptr){ LOG_WARNING("empty object"); return false; } use(objectPtr->getAttribute()); } The LOG_WARNING macro itself might have a high complexity, but it do not make the the function more complex to understand like e.g. a 'printf'. By default 'IgnoreMacros' is set to 'false', which is the original behavior of the check. Reviewed By: lebedev.ri, alexfh Differential Revision: https://reviews.llvm.org/D98070
2021-04-13 00:25:29 +08:00
// RUN: %check_clang_tidy -check-suffix=IGNORE-MACROS %s readability-function-cognitive-complexity %t -- \
// RUN: -config='{CheckOptions: \
// RUN: [{key: readability-function-cognitive-complexity.Threshold, \
// RUN: value: 0}, \
// RUN: {key: readability-function-cognitive-complexity.IgnoreMacros, \
// RUN: value: "true"}, \
// RUN: {key: readability-function-cognitive-complexity.DescribeBasicIncrements, \
// RUN: value: "false"} ]}'
// RUN: %check_clang_tidy -check-suffix=GLOBAL-IGNORE-MACROS %s readability-function-cognitive-complexity %t -- \
// RUN: -config='{CheckOptions: \
// RUN: [{key: readability-function-cognitive-complexity.Threshold, \
// RUN: value: 0}, \
// RUN: {key: IgnoreMacros, \
// RUN: value: "true"}, \
// RUN: {key: readability-function-cognitive-complexity.DescribeBasicIncrements, \
// RUN: value: "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]
[clang-tidy] Add option to ignore macros in readability-function-cognitive-complexity check. (this was originally part of https://reviews.llvm.org/D96281 and has been split off into its own patch) If a macro is used within a function, the code inside the macro doesn't make the code less readable. Instead, for a reader a macro is more like a function that is called. Thus the code inside a macro shouldn't increase the complexity of the function in which it is called. Thus the flag 'IgnoreMacros' is added. If set to 'true' code inside macros isn't considered during analysis. This isn't perfect, as now the code of a macro isn't considered at all, even if it has a high cognitive complexity itself. It might be better if a macro is considered in the analysis like a function and gets its own cognitive complexity. Implementing such an analysis seems to be very complex (if possible at all with the given AST), so we give the user the option to either ignore macros completely or to let the expanded code count to the calling function's complexity. See the code example from vgeof (originally added as note in https://reviews.llvm.org/D96281) bool doStuff(myClass* objectPtr){ if(objectPtr == nullptr){ LOG_WARNING("empty object"); return false; } if(objectPtr->getAttribute() == nullptr){ LOG_WARNING("empty object"); return false; } use(objectPtr->getAttribute()); } The LOG_WARNING macro itself might have a high complexity, but it do not make the the function more complex to understand like e.g. a 'printf'. By default 'IgnoreMacros' is set to 'false', which is the original behavior of the check. Reviewed By: lebedev.ri, alexfh Differential Revision: https://reviews.llvm.org/D98070
2021-04-13 00:25:29 +08:00
// 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-GLOBAL-IGNORE-MACROS: :[[@LINE-3]]:6: warning: function 'func_of_complexity_4' has cognitive complexity of 4 (threshold 0) [readability-function-cognitive-complexity]
if (1) {
if (1) {
}
}
if (1) {
}
}
#define MacroOfComplexity10 \
if (1) { \
if (1) { \
if (1) { \
if (1) { \
} \
} \
} \
}
void function_with_macro() {
// CHECK-NOTES: :[[@LINE-1]]:6: warning: function 'function_with_macro' has cognitive complexity of 11 (threshold 0) [readability-function-cognitive-complexity]
// CHECK-NOTES-THRESHOLD5: :[[@LINE-2]]:6: warning: function 'function_with_macro' has cognitive complexity of 11 (threshold 5) [readability-function-cognitive-complexity]
[clang-tidy] Add option to ignore macros in readability-function-cognitive-complexity check. (this was originally part of https://reviews.llvm.org/D96281 and has been split off into its own patch) If a macro is used within a function, the code inside the macro doesn't make the code less readable. Instead, for a reader a macro is more like a function that is called. Thus the code inside a macro shouldn't increase the complexity of the function in which it is called. Thus the flag 'IgnoreMacros' is added. If set to 'true' code inside macros isn't considered during analysis. This isn't perfect, as now the code of a macro isn't considered at all, even if it has a high cognitive complexity itself. It might be better if a macro is considered in the analysis like a function and gets its own cognitive complexity. Implementing such an analysis seems to be very complex (if possible at all with the given AST), so we give the user the option to either ignore macros completely or to let the expanded code count to the calling function's complexity. See the code example from vgeof (originally added as note in https://reviews.llvm.org/D96281) bool doStuff(myClass* objectPtr){ if(objectPtr == nullptr){ LOG_WARNING("empty object"); return false; } if(objectPtr->getAttribute() == nullptr){ LOG_WARNING("empty object"); return false; } use(objectPtr->getAttribute()); } The LOG_WARNING macro itself might have a high complexity, but it do not make the the function more complex to understand like e.g. a 'printf'. By default 'IgnoreMacros' is set to 'false', which is the original behavior of the check. Reviewed By: lebedev.ri, alexfh Differential Revision: https://reviews.llvm.org/D98070
2021-04-13 00:25:29 +08:00
// CHECK-NOTES-IGNORE-MACROS: :[[@LINE-3]]:6: warning: function 'function_with_macro' has cognitive complexity of 1 (threshold 0) [readability-function-cognitive-complexity]
// CHECK-NOTES-GLOBAL-IGNORE-MACROS: :[[@LINE-4]]:6: warning: function 'function_with_macro' has cognitive complexity of 11 (threshold 0) [readability-function-cognitive-complexity]
MacroOfComplexity10;
if (1) {
}
}
[clang-tidy] Add option to ignore macros in readability-function-cognitive-complexity check. (this was originally part of https://reviews.llvm.org/D96281 and has been split off into its own patch) If a macro is used within a function, the code inside the macro doesn't make the code less readable. Instead, for a reader a macro is more like a function that is called. Thus the code inside a macro shouldn't increase the complexity of the function in which it is called. Thus the flag 'IgnoreMacros' is added. If set to 'true' code inside macros isn't considered during analysis. This isn't perfect, as now the code of a macro isn't considered at all, even if it has a high cognitive complexity itself. It might be better if a macro is considered in the analysis like a function and gets its own cognitive complexity. Implementing such an analysis seems to be very complex (if possible at all with the given AST), so we give the user the option to either ignore macros completely or to let the expanded code count to the calling function's complexity. See the code example from vgeof (originally added as note in https://reviews.llvm.org/D96281) bool doStuff(myClass* objectPtr){ if(objectPtr == nullptr){ LOG_WARNING("empty object"); return false; } if(objectPtr->getAttribute() == nullptr){ LOG_WARNING("empty object"); return false; } use(objectPtr->getAttribute()); } The LOG_WARNING macro itself might have a high complexity, but it do not make the the function more complex to understand like e.g. a 'printf'. By default 'IgnoreMacros' is set to 'false', which is the original behavior of the check. Reviewed By: lebedev.ri, alexfh Differential Revision: https://reviews.llvm.org/D98070
2021-04-13 00:25:29 +08:00
#define noop \
{}
#define SomeMacro(x) \
if (1) { \
x; \
}
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-GLOBAL-IGNORE-MACROS: :[[@LINE-3]]:6: warning: function 'func_macro_1' has cognitive complexity of 2 (threshold 0) [readability-function-cognitive-complexity]
if (1) {
}
SomeMacro(noop);
}
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-GLOBAL-IGNORE-MACROS: :[[@LINE-3]]:6: warning: function 'func_macro_2' has cognitive complexity of 4 (threshold 0) [readability-function-cognitive-complexity]
if (1) {
}
// Note that if the IgnoreMacro option is set to 'true', currently also macro
// arguments are ignored. Optimally, macros should be treated like function
// calls, i.e. the arguments account to the complexity so that the overall
// complexity of this function is 2 (1 for the if statement above + 1 for
// the if statement in the argument).
SomeMacro(if (1) { noop; });
}