@@ -16,12 +16,6 @@ import cpp
16
16
import codingstandards.c.misra
17
17
import codingstandards.c.TgMath
18
18
19
- Expr getFullyExplicitlyConverted ( Expr e ) {
20
- if e .hasExplicitConversion ( )
21
- then result = getFullyExplicitlyConverted ( e .getExplicitlyConverted ( ) )
22
- else result = e
23
- }
24
-
25
19
string argTypesString ( TgMathInvocation call , int i ) {
26
20
exists ( string typeStr |
27
21
typeStr = getEffectiveStandardType ( call .getOperandArgument ( i ) ) .toString ( ) and
@@ -33,12 +27,28 @@ string argTypesString(TgMathInvocation call, int i) {
33
27
)
34
28
}
35
29
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 ( )
42
52
}
43
53
44
54
Type canonicalize ( Type type ) {
@@ -48,8 +58,7 @@ Type canonicalize(Type type) {
48
58
}
49
59
50
60
Type getEffectiveStandardType ( Expr e ) {
51
- result =
52
- canonicalize ( integerPromote ( getFullyExplicitlyConverted ( e ) .getType ( ) .stripTopLevelSpecifiers ( ) ) )
61
+ result = canonicalize ( getPromotedType ( e .getExplicitlyConverted ( ) ) )
53
62
}
54
63
55
64
from TgMathInvocation call , Type firstType
0 commit comments