Skip to content

Commit 642c737

Browse files
Handle bit fields
1 parent 6148518 commit 642c737

File tree

1 file changed

+23
-14
lines changed

1 file changed

+23
-14
lines changed

c/misra/src/rules/RULE-21-23/TgMathArgumentsWithDifferingStandardType.ql

+23-14
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@ import cpp
1616
import codingstandards.c.misra
1717
import codingstandards.c.TgMath
1818

19-
Expr getFullyExplicitlyConverted(Expr e) {
20-
if e.hasExplicitConversion()
21-
then result = getFullyExplicitlyConverted(e.getExplicitlyConverted())
22-
else result = e
23-
}
24-
2519
string argTypesString(TgMathInvocation call, int i) {
2620
exists(string typeStr |
2721
typeStr = getEffectiveStandardType(call.getOperandArgument(i)).toString() and
@@ -33,12 +27,28 @@ string argTypesString(TgMathInvocation call, int i) {
3327
)
3428
}
3529

36-
predicate promotes(Type type) { type.(IntegralType).getSize() < any(IntType t).getSize() }
37-
38-
Type integerPromote(Type type) {
39-
promotes(type) and result.(IntType).isSigned()
40-
or
41-
not promotes(type) and result = type
30+
/**
31+
* If the range of values can be represented as a signed int, it is promoted to signed int.
32+
*
33+
* A value may also promote to unsigned int but only if `int` cannot represent the range of
34+
* values. Which basically means only an `unsigned int` promotes to `unsigned int`, so we don't
35+
* need to do anything in this case.
36+
*
37+
* An unsigned int bitfield with fewer than 32 bits is promoted to `int`.
38+
*/
39+
predicate promotesToSignedInt(Expr e) {
40+
exists(int intBits, int intBytes |
41+
intBytes = any(IntType t).getSize() and
42+
intBits = intBytes * 8 and
43+
(
44+
e.(FieldAccess).getTarget().(BitField).getNumBits() < intBits
45+
or
46+
e.getUnderlyingType().(IntegralType).getSize() < intBytes
47+
)
48+
)
49+
}
50+
Type getPromotedType(Expr e) {
51+
if promotesToSignedInt(e) then result.(IntType).isSigned() else result = e.getUnderlyingType()
4252
}
4353

4454
Type canonicalize(Type type) {
@@ -48,8 +58,7 @@ Type canonicalize(Type type) {
4858
}
4959

5060
Type getEffectiveStandardType(Expr e) {
51-
result =
52-
canonicalize(integerPromote(getFullyExplicitlyConverted(e).getType().stripTopLevelSpecifiers()))
61+
result = canonicalize(getPromotedType(e.getExplicitlyConverted()))
5362
}
5463

5564
from TgMathInvocation call, Type firstType

0 commit comments

Comments
 (0)