Skip to content

Commit 2f50b03

Browse files
committed
RULE-8-2-10: Avoid callers of recursive functions being flagged
The rule forbids only recursive functions. It can be fair to have a recursive function and justify this within one. With the behavior before this change, also every caller would need to be argued. This is additonal burden that is not required and intended by the MISRA standard. Fixes #935
1 parent 883a46f commit 2f50b03

5 files changed

Lines changed: 14 additions & 8 deletions

File tree

c/misra/test/rules/RULE-17-2/test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ void f3() {
88
f3(); // NON_COMPLIANT
99
}
1010
void f6() {
11-
f3(); // NON_COMPLIANT
11+
f3(); // COMPLIANT - merely calls a recursive function
1212
}
1313

1414
void f5() {
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`A7-5-2`, `RULE-8-2-10`: `FunctionsCallThemselvesEitherDirectlyOrIndirectly.ql`:
2+
- Fix false positives where callers of recursive functions were incorrectly reported as recursive. Only calls that participate in a recursive cycle are now reported.

cpp/common/src/codingstandards/cpp/rules/functionscallthemselveseitherdirectlyorindirectly/FunctionsCallThemselvesEitherDirectlyOrIndirectly.qll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ class RecursiveFunction extends Function {
2323
RecursiveFunction() { exists(RecursiveCall fc | fc.getEnclosingFunction() = this) }
2424
}
2525

26-
query predicate problems(FunctionCall fc, string message, RecursiveFunction f, string functionName) {
26+
query predicate problems(RecursiveCall fc, string message, Function f, string functionName) {
2727
not isExcluded(fc, getQuery()) and
2828
f = fc.getTarget() and
2929
functionName = f.getName() and
3030
if f = fc.getEnclosingFunction()
3131
then message = "This call directly invokes its containing function $@."
3232
else
3333
message =
34-
"The function " + fc.getEnclosingFunction() + " is indirectly recursive via this call to $@."
34+
"The function " + fc.getEnclosingFunction() +
35+
" is indirectly recursive via this call to $@."
3536
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
| test.cpp:7:13:7:35 | call to test_recursive_function | This call directly invokes its containing function $@. | test.cpp:5:5:5:27 | test_recursive_function | test_recursive_function |
2-
| test.cpp:21:9:21:31 | call to test_recursive_function | The function test_indirect_recursive_function is indirectly recursive via this call to $@. | test.cpp:5:5:5:27 | test_recursive_function | test_recursive_function |
3-
| test.cpp:27:5:27:30 | call to test_indirect_recursive_f2 | The function test_indirect_recursive_f1 is indirectly recursive via this call to $@. | test.cpp:36:5:36:30 | test_indirect_recursive_f2 | test_indirect_recursive_f2 |
4-
| test.cpp:38:9:38:34 | call to test_indirect_recursive_f1 | The function test_indirect_recursive_f2 is indirectly recursive via this call to $@. | test.cpp:25:5:25:30 | test_indirect_recursive_f1 | test_indirect_recursive_f1 |
5-
| test.cpp:75:10:75:19 | call to operator== | This call directly invokes its containing function $@. | test.cpp:74:6:74:15 | operator== | operator== |
2+
| test.cpp:31:5:31:30 | call to test_indirect_recursive_f2 | The function test_indirect_recursive_f1 is indirectly recursive via this call to $@. | test.cpp:40:5:40:30 | test_indirect_recursive_f2 | test_indirect_recursive_f2 |
3+
| test.cpp:42:9:42:34 | call to test_indirect_recursive_f1 | The function test_indirect_recursive_f2 is indirectly recursive via this call to $@. | test.cpp:29:5:29:30 | test_indirect_recursive_f1 | test_indirect_recursive_f1 |
4+
| test.cpp:79:10:79:19 | call to operator== | This call directly invokes its containing function $@. | test.cpp:78:6:78:15 | operator== | operator== |

cpp/common/test/rules/functionscallthemselveseitherdirectlyorindirectly/test.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ int test_nonrecursive_function(int i) { // COMPLIANT
1818

1919
int test_indirect_recursive_function(int i) {
2020
if (i > 10) {
21-
i = test_recursive_function(i * i); // NON_COMPLIANT
21+
i = test_recursive_function(i * i); // COMPLIANT - merely calls a recursive function
2222
}
2323
}
2424

25+
int test_calls_recursive_function(int i) {
26+
return test_recursive_function(i); // COMPLIANT - not part of a recursive cycle
27+
}
28+
2529
int test_indirect_recursive_f1(int i) {
2630
if (i > 10) {
2731
test_indirect_recursive_f2(i + i); // NON_COMPLIANT

0 commit comments

Comments
 (0)