Skip to content

Commit 7c5fea9

Browse files
committed
EssentialTypes: Implement Rule 10.1
Adds queries to identify operators where the operands are of an inappropriate essential type, according to the MISRA specified rules.
1 parent 79e44e3 commit 7c5fea9

7 files changed

+964
-0
lines changed
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/**
2+
* @id c/misra/operands-of-an-inappropriate-essential-type
3+
* @name RULE-10-1: Operands shall not be of an inappropriate essential type
4+
* @description
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-10-1
9+
* external/misra/obligation/required
10+
*/
11+
12+
import cpp
13+
import codingstandards.c.misra
14+
import codingstandards.c.misra.EssentialTypes
15+
16+
/**
17+
* Holds if the operator `operator` has an operand `child` that is of an inappropriate essential type
18+
* according to MISRA C 2012 Rule 10.1.
19+
*/
20+
predicate isInappropriateEssentialType(
21+
Expr operator, Expr child, EssentialTypeCategory etc, int rationaleId
22+
) {
23+
etc = getEssentialTypeCategory(getEssentialType(child)) and
24+
(
25+
child = operator.(ArrayExpr).getArrayOffset() and
26+
(
27+
etc = EssentiallyBooleanType() and
28+
rationaleId = 3
29+
or
30+
etc = EssentiallyCharacterType() and
31+
rationaleId = 4
32+
or
33+
etc = EssentiallyFloatingType() and
34+
rationaleId = 1
35+
)
36+
or
37+
child = operator.(UnaryPlusExpr).getOperand() and
38+
(
39+
etc = EssentiallyBooleanType() and
40+
rationaleId = 3
41+
or
42+
etc = EssentiallyCharacterType() and
43+
rationaleId = 4
44+
or
45+
etc = EssentiallyEnumType() and
46+
rationaleId = 5
47+
)
48+
or
49+
child = operator.(UnaryMinusExpr).getOperand() and
50+
(
51+
etc = EssentiallyBooleanType() and
52+
rationaleId = 3
53+
or
54+
etc = EssentiallyCharacterType() and
55+
rationaleId = 4
56+
or
57+
etc = EssentiallyEnumType() and
58+
rationaleId = 5
59+
or
60+
etc = EssentiallyUnsignedType() and
61+
rationaleId = 8
62+
)
63+
or
64+
// The table only talks about + and -, but below it clarifies ++ and -- are also considered to
65+
// be equivalent.
66+
child =
67+
[
68+
operator.(AddExpr).getAnOperand(), operator.(SubExpr).getAnOperand(),
69+
operator.(IncrementOperation).getAnOperand(), operator.(DecrementOperation).getAnOperand(),
70+
operator.(AssignAddExpr).getAnOperand(), operator.(AssignSubExpr).getAnOperand()
71+
] and
72+
(
73+
etc = EssentiallyBooleanType() and
74+
rationaleId = 3
75+
or
76+
etc = EssentiallyEnumType() and
77+
rationaleId = 5
78+
)
79+
or
80+
child =
81+
[
82+
operator.(DivExpr).getAnOperand(), operator.(MulExpr).getAnOperand(),
83+
operator.(AssignDivExpr).getAnOperand(), operator.(AssignMulExpr).getAnOperand()
84+
] and
85+
(
86+
etc = EssentiallyBooleanType() and
87+
rationaleId = 3
88+
or
89+
etc = EssentiallyCharacterType() and
90+
rationaleId = 4
91+
or
92+
etc = EssentiallyEnumType() and
93+
rationaleId = 5
94+
)
95+
or
96+
child = [operator.(RemExpr).getAnOperand(), operator.(AssignRemExpr).getAnOperand()] and
97+
(
98+
etc = EssentiallyBooleanType() and
99+
rationaleId = 3
100+
or
101+
etc = EssentiallyCharacterType() and
102+
rationaleId = 4
103+
or
104+
etc = EssentiallyEnumType() and
105+
rationaleId = 5
106+
or
107+
etc = EssentiallyFloatingType() and
108+
rationaleId = 1
109+
)
110+
or
111+
child = operator.(RelationalOperation).getAnOperand() and
112+
etc = EssentiallyBooleanType() and
113+
rationaleId = 3
114+
or
115+
child = [operator.(NotExpr).getAnOperand(), operator.(BinaryLogicalOperation).getAnOperand()] and
116+
rationaleId = 2 and
117+
(
118+
etc = EssentiallyCharacterType()
119+
or
120+
etc = EssentiallyEnumType()
121+
or
122+
etc = EssentiallySignedType()
123+
or
124+
etc = EssentiallyUnsignedType()
125+
or
126+
etc = EssentiallyFloatingType()
127+
)
128+
or
129+
child =
130+
[
131+
operator.(LShiftExpr).getLeftOperand(), operator.(RShiftExpr).getLeftOperand(),
132+
operator.(AssignLShiftExpr).getLValue(), operator.(AssignRShiftExpr).getLValue()
133+
] and
134+
(
135+
etc = EssentiallyBooleanType() and
136+
rationaleId = 3
137+
or
138+
etc = EssentiallyCharacterType() and
139+
rationaleId = 4
140+
or
141+
etc = EssentiallyEnumType() and
142+
rationaleId = 6 // 5 also applies, but 6 is sufficient explanation
143+
or
144+
etc = EssentiallySignedType() and
145+
rationaleId = 6
146+
or
147+
etc = EssentiallyFloatingType() and
148+
rationaleId = 1
149+
)
150+
or
151+
child =
152+
[
153+
operator.(LShiftExpr).getRightOperand(), operator.(RShiftExpr).getRightOperand(),
154+
operator.(AssignLShiftExpr).getRValue(), operator.(AssignRShiftExpr).getRValue()
155+
] and
156+
// Integer constant non negative essentially signed types are allowed by exception
157+
not (child.getValue().toInt() >= 0 and etc = EssentiallySignedType()) and
158+
(
159+
etc = EssentiallyBooleanType() and
160+
rationaleId = 3
161+
or
162+
etc = EssentiallyCharacterType() and
163+
rationaleId = 4
164+
or
165+
etc = EssentiallyEnumType() and
166+
rationaleId = 7
167+
or
168+
etc = EssentiallySignedType() and
169+
rationaleId = 7
170+
or
171+
etc = EssentiallyFloatingType() and
172+
rationaleId = 1
173+
)
174+
or
175+
child =
176+
[
177+
operator.(BinaryBitwiseOperation).getAnOperand(),
178+
operator.(AssignBitwiseOperation).getAnOperand()
179+
] and
180+
not operator instanceof LShiftExpr and
181+
not operator instanceof RShiftExpr and
182+
not operator instanceof AssignLShiftExpr and
183+
not operator instanceof AssignRShiftExpr and
184+
(
185+
etc = EssentiallyBooleanType() and
186+
rationaleId = 3
187+
or
188+
etc = EssentiallyCharacterType() and
189+
rationaleId = 4
190+
or
191+
etc = EssentiallyEnumType() and
192+
rationaleId = 6
193+
or
194+
etc = EssentiallySignedType() and
195+
rationaleId = 6
196+
or
197+
etc = EssentiallyFloatingType() and
198+
rationaleId = 1
199+
)
200+
or
201+
child = operator.(ConditionalExpr).getCondition() and
202+
(
203+
etc = EssentiallyCharacterType() and
204+
rationaleId = 2
205+
or
206+
etc = EssentiallyEnumType() and
207+
rationaleId = 2
208+
or
209+
etc = EssentiallySignedType() and
210+
rationaleId = 2
211+
or
212+
etc = EssentiallyUnsignedType() and
213+
rationaleId = 2
214+
or
215+
etc = EssentiallyFloatingType() and
216+
rationaleId = 2
217+
)
218+
)
219+
}
220+
221+
string getRationaleMessage(int rationaleId, EssentialTypeCategory etc) {
222+
rationaleId = 1 and
223+
result = "Constraint violation from using an operand of essentially Floating type."
224+
or
225+
rationaleId = 2 and result = "Operand of " + etc + " type interpreted as a Boolean value."
226+
or
227+
rationaleId = 3 and result = "Operand of essentially Boolean type interpreted as a numeric value."
228+
or
229+
rationaleId = 4 and
230+
result = "Operand of essentially Charater type interpreted as a numeric value."
231+
or
232+
rationaleId = 5 and
233+
result =
234+
"Operand of essentially Enum type used in arithmetic operation, but has an implementation defined integer type."
235+
or
236+
rationaleId = 6 and
237+
result = "Bitwise operator applied to operand of " + etc + " and not essentially unsigned."
238+
or
239+
rationaleId = 7 and
240+
result = "Right hand operatand of shift operator is " + etc + " and not not essentially unsigned."
241+
or
242+
rationaleId = 8 and
243+
result =
244+
"Operand of essentially Unsigned type will be converted to a signed type with the signedness dependent on the implemented size of int."
245+
}
246+
247+
from Expr operator, Expr child, int rationaleId, EssentialTypeCategory etc
248+
where
249+
not isExcluded(operator, EssentialTypesPackage::operandsOfAnInappropriateEssentialTypeQuery()) and
250+
isInappropriateEssentialType(operator, child, etc, rationaleId)
251+
select operator, getRationaleMessage(rationaleId, etc)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/pointer-type-on-logical-operator
3+
* @name RULE-10-1: Logical operators should not be used with pointer types
4+
* @description
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-10-1
9+
* external/misra/obligation/required
10+
*/
11+
12+
import cpp
13+
import codingstandards.c.misra
14+
15+
from Expr logicalOperator, Expr operand
16+
where
17+
not isExcluded(operand, EssentialTypesPackage::pointerTypeOnLogicalOperatorQuery()) and
18+
(
19+
operand = logicalOperator.(BinaryLogicalOperation).getAnOperand()
20+
or
21+
operand = logicalOperator.(NotExpr).getOperand()
22+
) and
23+
operand.getType() instanceof PointerType
24+
select operand, "Logical operators should not be used with pointer types."

0 commit comments

Comments
 (0)