Skip to content

Commit 1a1dbba

Browse files
committed
WIP 15-3
1 parent 88be969 commit 1a1dbba

File tree

2 files changed

+64
-17
lines changed

2 files changed

+64
-17
lines changed
Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @id c/misra/goto-label-block-condition
3-
* @name RULE-15-3: The goto statement and any of its label shall be declared or enclosed in the same block.
3+
* @name RULE-15-3: The goto statement and any of its label shall be declared or enclosed in the same block.
44
* @description Any label referenced by a goto statement shall be declared in the same block, or in
55
* any block enclosing the goto statement
66
* @kind problem
@@ -15,33 +15,67 @@
1515
import cpp
1616
import codingstandards.c.misra
1717

18+
predicate isPartOfSwitch(Stmt goto) {
19+
exists(SwitchStmt switch | switch.getStmt() = goto.getParent())
20+
}
21+
22+
Stmt getNextStmt(ControlFlowNode node) {
23+
node.getASuccessor() = result
24+
or
25+
exists(ControlFlowNode other |
26+
node.getASuccessor() = other and other != result and result = getNextStmt(other)
27+
)
28+
}
29+
30+
Stmt getPreviousStmt(Stmt s) { s = getNextStmt(result) }
31+
32+
SwitchCase getSwitchCase(Stmt stmt) {
33+
exists(int index, SwitchStmt switch |
34+
getStmtInSwitch(switch, stmt, index) and getStmtInSwitch(switch, result, index - 1)
35+
)
36+
or
37+
exists(int index, SwitchStmt switch, Stmt other |
38+
getStmtInSwitch(switch, stmt, index) and
39+
getStmtInSwitch(switch, other, index - 1) and
40+
not other instanceof SwitchCase and
41+
result = getSwitchCase(other)
42+
)
43+
}
44+
45+
predicate getStmtInSwitch(SwitchStmt switch, Stmt s, int index) {
46+
switch.getStmt().(BlockStmt).getStmt(index) = s
47+
}
48+
1849
int statementDepth(Stmt statement) {
1950
statement.getParent() = statement.getEnclosingFunction().getBlock() and result = 1
2051
or
2152
statementDepth(statement.getParent()) + 1 = result
2253
}
2354

2455
predicate test(GotoStmt goto, Stmt target, int m, int n) {
25-
statementDepth(goto) = m and target = goto.getTarget() and statementDepth(target) = n
56+
statementDepth(goto) = m and
57+
target = goto.getTarget() and
58+
statementDepth(target) = n and
59+
isPartOfSwitch(goto) and
60+
getSwitchCase(goto) = getSwitchCase(target) and
61+
m = n
2662
}
2763

28-
from GotoStmt goto
64+
from GotoStmt goto, Stmt target, int gotoDepth, int targetDepth
2965
where
3066
not isExcluded(goto, Statements2Package::gotoLabelBlockConditionQuery()) and
31-
not goto.getEnclosingBlock+() = goto.getTarget().getEnclosingBlock()
32-
or
33-
exists(SwitchStmt switch, int caseLocation, int nextCaseLocation |
34-
switch.getAChild*() = goto and
35-
switch.getASwitchCase().getLocation().getStartLine() = caseLocation and
36-
switch.getASwitchCase().getNextSwitchCase().getLocation().getStartLine() = nextCaseLocation and
37-
goto.getLocation().getStartLine() > caseLocation and
38-
goto.getLocation().getStartLine() < nextCaseLocation and
67+
goto.getTarget() = target and
68+
gotoDepth = statementDepth(goto) and
69+
targetDepth = statementDepth(target) and
70+
targetDepth >= gotoDepth and
71+
(
72+
targetDepth = gotoDepth
73+
implies
3974
(
40-
goto.getTarget().getLocation().getStartLine() < caseLocation
75+
not isPartOfSwitch(goto) and not goto.getParent() = target.getParent()
4176
or
42-
goto.getTarget().getLocation().getStartLine() > nextCaseLocation
43-
) and
44-
goto.getTarget().getLocation().getStartLine() > switch.getLocation().getStartLine()
77+
isPartOfSwitch(goto) and not getSwitchCase(goto) = getSwitchCase(target)
78+
)
4579
)
4680
select goto, "The $@ statement and its $@ are not declared or enclosed in the same block. test",
47-
goto, "goto", goto.getTarget(), "label"
81+
goto, "goto", target, "label"

c/misra/test/rules/RULE-15-3/test.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,17 @@ void f7(int p) {
6666
default:
6767
break;
6868
}
69-
}
69+
}
70+
71+
void f8(int p) {
72+
73+
switch (p) {
74+
case 0:
75+
goto L1;
76+
;
77+
L1:; // COMPLIANT
78+
break;
79+
default:
80+
break;
81+
}
82+
}

0 commit comments

Comments
 (0)