Skip to content

Commit ffcb432

Browse files
committed
Add agent-generated first draft
1 parent c8f559c commit ffcb432

File tree

3 files changed

+368
-4
lines changed

3 files changed

+368
-4
lines changed

cpp/misra/src/rules/RULE-9-4-2/AppropriateStructureOfSwitchStatement.ql

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,54 @@
1818

1919
import cpp
2020
import codingstandards.cpp.misra
21+
import codingstandards.cpp.SwitchStatement
2122

22-
from
23+
from SwitchStmt switch, string message
2324
where
24-
not isExcluded(x, StatementsPackage::appropriateStructureOfSwitchStatementQuery()) and
25-
select
25+
not isExcluded(switch, StatementsPackage::appropriateStructureOfSwitchStatementQuery()) and
26+
(
27+
// RULE-16-1: Switch not well-formed (has inappropriate statements)
28+
exists(SwitchCase case |
29+
case = switch.getASwitchCase() and
30+
switchCaseNotWellFormed(case) and
31+
message = "has a case that contains inappropriate statements (only expression, compound, selection, iteration or try statements are allowed)"
32+
)
33+
or
34+
// RULE-16-2: Nested switch labels
35+
exists(SwitchCase case |
36+
case = switch.getASwitchCase() and
37+
case instanceof NestedSwitchCase and
38+
message = "contains a switch label that is not directly within the switch body"
39+
)
40+
or
41+
// RULE-16-3: Non-empty case doesn't terminate with break
42+
exists(SwitchCase case |
43+
case = switch.getASwitchCase() and
44+
case instanceof CaseDoesNotTerminate and
45+
message = "has a non-empty case that does not terminate with an unconditional break or throw statement"
46+
)
47+
or
48+
// RULE-16-4: Missing default clause
49+
not switch.hasDefaultCase() and
50+
message = "is missing a default clause"
51+
or
52+
// RULE-16-5: Default clause not first or last
53+
exists(SwitchCase defaultCase |
54+
switch.getDefaultCase() = defaultCase and
55+
exists(defaultCase.getPreviousSwitchCase()) and
56+
finalClauseInSwitchNotDefault(switch) and
57+
message = "has a default clause that is not the first or last switch label"
58+
)
59+
or
60+
// RULE-16-6: Less than two case clauses
61+
count(SwitchCase case |
62+
switch.getASwitchCase() = case and
63+
case.getNextSwitchCase() != case.getFollowingStmt()
64+
) + 1 < 2 and
65+
message = "has fewer than two switch-clauses"
66+
or
67+
// RULE-16-7: Boolean switch expression
68+
switch instanceof BooleanSwitchStmt and
69+
message = "has a controlling expression of essentially Boolean type"
70+
)
71+
select switch, "Switch statement " + message + "."
Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
1-
No expected results have yet been specified
1+
| test.cpp:40:3:40:8 | Switch statement has a case that contains inappropriate statements (only expression, compound, selection, iteration or try statements are allowed). |
2+
| test.cpp:86:3:86:8 | Switch statement has a non-empty case that does not terminate with an unconditional break or throw statement. |
3+
| test.cpp:86:3:86:8 | Switch statement has a non-empty case that does not terminate with an unconditional break or throw statement. |
4+
| test.cpp:98:3:98:8 | Switch statement has a non-empty case that does not terminate with an unconditional break or throw statement. |
5+
| test.cpp:123:3:123:8 | Switch statement is missing a default clause. |
6+
| test.cpp:166:3:166:8 | Switch statement has a default clause that is not the first or last switch label. |
7+
| test.cpp:203:3:203:8 | Switch statement has fewer than two switch-clauses. |
8+
| test.cpp:210:3:210:8 | Switch statement has fewer than two switch-clauses. |
9+
| test.cpp:235:3:235:8 | Switch statement has a controlling expression of essentially Boolean type. |
10+
| test.cpp:245:3:245:8 | Switch statement has a controlling expression of essentially Boolean type. |
11+
| test.cpp:266:3:266:8 | Switch statement has a controlling expression of essentially Boolean type. |
12+
| test.cpp:266:3:266:8 | Switch statement is missing a default clause. |
13+
| test.cpp:266:3:266:8 | Switch statement has fewer than two switch-clauses. |
14+
| test.cpp:275:3:275:8 | Switch statement has a non-empty case that does not terminate with an unconditional break or throw statement. |
15+
| test.cpp:275:3:275:8 | Switch statement has a default clause that is not the first or last switch label. |
Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
// Test cases for RULE-9-4-2: The structure of a switch statement shall be
2+
// appropriate This rule combines RULE-16-1 through RULE-16-7
3+
4+
void test_rule_16_1_well_formed(int expr) {
5+
int i = 0;
6+
7+
// COMPLIANT - well-formed switch with proper statements
8+
switch (expr) {
9+
case 1:
10+
i++; // expression statement
11+
break;
12+
case 2: { // compound statement
13+
i++;
14+
} break;
15+
case 3:
16+
if (i > 0) { // selection statement
17+
i++;
18+
}
19+
break;
20+
case 4:
21+
while (i < 10) { // iteration statement
22+
i++;
23+
}
24+
break;
25+
default:
26+
break;
27+
}
28+
29+
// NON_COMPLIANT - switch with inappropriate statement (declaration)
30+
switch (expr) {
31+
case 1:
32+
int j = 5; // declaration statement - not allowed
33+
break;
34+
default:
35+
break;
36+
}
37+
}
38+
39+
void test_rule_16_2_nested_labels(int expr) {
40+
// COMPLIANT - labels directly within switch body
41+
switch (expr) {
42+
case 1:
43+
break;
44+
case 2:
45+
break;
46+
default:
47+
break;
48+
}
49+
50+
// NON_COMPLIANT - nested switch labels (this would be a compiler error in
51+
// practice) switch (expr) { case 1:
52+
// {
53+
// case 2: // nested label - not allowed
54+
// break;
55+
// }
56+
// break;
57+
// default:
58+
// break;
59+
// }
60+
}
61+
62+
void test_rule_16_3_termination(int expr) {
63+
int i = 0;
64+
65+
// COMPLIANT - all cases properly terminated
66+
switch (expr) {
67+
case 1:
68+
i++;
69+
break;
70+
case 2:
71+
case 3: // empty cases are fine
72+
i++;
73+
break;
74+
case 4:
75+
throw "error"; // throw is also valid termination
76+
default:
77+
break;
78+
}
79+
80+
// NON_COMPLIANT - case 1 falls through without break
81+
switch (expr) {
82+
case 1: // NON_COMPLIANT - missing break
83+
i++;
84+
case 2: // COMPLIANT - properly terminated
85+
i++;
86+
break;
87+
default:
88+
break;
89+
}
90+
91+
// NON_COMPLIANT - default case falls through
92+
switch (expr) {
93+
case 1:
94+
i++;
95+
break;
96+
default: // NON_COMPLIANT - missing break
97+
i++;
98+
}
99+
}
100+
101+
void test_rule_16_4_default_label(int expr) {
102+
int i = 0;
103+
104+
// COMPLIANT - has default label
105+
switch (expr) {
106+
case 1:
107+
i++;
108+
break;
109+
case 2:
110+
i++;
111+
break;
112+
default:
113+
break;
114+
}
115+
116+
// NON_COMPLIANT - missing default label
117+
switch (expr) {
118+
case 1:
119+
i++;
120+
break;
121+
case 2:
122+
i++;
123+
break;
124+
}
125+
}
126+
127+
void test_rule_16_5_default_position(int expr) {
128+
int i = 0;
129+
130+
// COMPLIANT - default is first
131+
switch (expr) {
132+
default:
133+
i++;
134+
break;
135+
case 1:
136+
i++;
137+
break;
138+
case 2:
139+
i++;
140+
break;
141+
}
142+
143+
// COMPLIANT - default is last
144+
switch (expr) {
145+
case 1:
146+
i++;
147+
break;
148+
case 2:
149+
i++;
150+
break;
151+
default:
152+
i++;
153+
break;
154+
}
155+
156+
// NON_COMPLIANT - default is in the middle
157+
switch (expr) {
158+
case 1:
159+
i++;
160+
break;
161+
default: // NON_COMPLIANT - not first or last
162+
i++;
163+
break;
164+
case 2:
165+
i++;
166+
break;
167+
}
168+
}
169+
170+
void test_rule_16_6_two_clauses(int expr) {
171+
int i = 0;
172+
173+
// COMPLIANT - has multiple clauses
174+
switch (expr) {
175+
case 1:
176+
i++;
177+
break;
178+
case 2:
179+
i++;
180+
break;
181+
default:
182+
break;
183+
}
184+
185+
// NON_COMPLIANT - only has default (single clause)
186+
switch (expr) {
187+
default:
188+
i++;
189+
break;
190+
}
191+
192+
// NON_COMPLIANT - only has one case plus default (still only one effective
193+
// clause)
194+
switch (expr) {
195+
case 1:
196+
default:
197+
i++;
198+
break;
199+
}
200+
}
201+
202+
void test_rule_16_7_boolean_expression() {
203+
int i = 0;
204+
bool flag = true;
205+
206+
// COMPLIANT - non-boolean expression
207+
switch (i) {
208+
case 0:
209+
break;
210+
case 1:
211+
break;
212+
default:
213+
break;
214+
}
215+
216+
// NON_COMPLIANT - boolean expression
217+
switch (flag) {
218+
case true:
219+
break;
220+
case false:
221+
break;
222+
default:
223+
break;
224+
}
225+
226+
// NON_COMPLIANT - boolean comparison expression
227+
switch (i == 0) {
228+
case true:
229+
break;
230+
case false:
231+
break;
232+
default:
233+
break;
234+
}
235+
}
236+
237+
int f() { return 1; }
238+
239+
void test_complex_violations(int expr) {
240+
int i = 0;
241+
bool flag = true;
242+
243+
// NON_COMPLIANT - multiple violations:
244+
// - Boolean expression (16-7)
245+
// - Missing default (16-4)
246+
// - Single clause (16-6)
247+
switch (flag) {
248+
case true:
249+
i++;
250+
}
251+
252+
// NON_COMPLIANT - multiple violations:
253+
// - Fall-through case (16-3)
254+
// - Default not first/last (16-5)
255+
switch (expr) {
256+
case 1: // NON_COMPLIANT - falls through
257+
i++;
258+
default: // NON_COMPLIANT - not first/last
259+
i++;
260+
break;
261+
case 2:
262+
i++;
263+
break;
264+
}
265+
266+
switch (expr) {
267+
int i = 0;
268+
case 1:
269+
i++;
270+
}
271+
272+
switch (int x = f(); x) {
273+
case 1:
274+
i++;
275+
}
276+
277+
switch (expr = f(); expr) {
278+
case 1:
279+
i++;
280+
}
281+
282+
switch (expr) {
283+
case 1:
284+
{
285+
case 2:
286+
i++;
287+
}
288+
}
289+
290+
switch (expr) {
291+
case 1: {
292+
i++;
293+
goto someLabel;
294+
someLabel:
295+
i++;
296+
}
297+
}
298+
299+
switch (expr) {
300+
int x = 1;
301+
case 1:
302+
i++;
303+
}
304+
}

0 commit comments

Comments
 (0)