Skip to content

Commit bc7bf51

Browse files
committed
Rule 7.0.5: Limit to Casts and refactor naming
- Only `Cast`s participate in integer promotions and arithmetic conversions. - Rename conversion classes to clarify what they cover. - Update documentation to improve clarity on coverage.
1 parent 21cf410 commit bc7bf51

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

cpp/misra/src/rules/RULE-7-0-5/NoSignednessChangeFromPromotion.ql

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@ import cpp
1717
import codingstandards.cpp.misra
1818
import codingstandards.cpp.misra.BuiltInTypeRules
1919

20-
abstract class RelevantConversion extends Expr {
20+
/**
21+
* An expression that represents a integral promotion or usual arithmetic conversion.
22+
*
23+
* Such conversions are usual either explicitly described with a `Cast`, or, in the case
24+
* of assign operations, implicitly applied to an lvalue.
25+
*/
26+
abstract class IntegerPromotionOrUsualArithmeticConversion extends Expr {
2127
abstract NumericType getFromType();
2228

2329
abstract NumericType getToType();
@@ -28,13 +34,15 @@ abstract class RelevantConversion extends Expr {
2834
}
2935

3036
/**
31-
* A `Conversion` that is relevant for the rule.
37+
* A `Cast` which is either an integer promotion or usual arithmetic conversion.
3238
*/
33-
abstract class RelevantRealConversion extends RelevantConversion, Conversion {
39+
abstract class IntegerPromotionOrUsualArithmeticConversionAsCast extends IntegerPromotionOrUsualArithmeticConversion,
40+
Cast
41+
{
3442
NumericType fromType;
3543
NumericType toType;
3644

37-
RelevantRealConversion() {
45+
IntegerPromotionOrUsualArithmeticConversionAsCast() {
3846
fromType = this.getExpr().getType() and
3947
toType = this.getType() and
4048
this.isImplicit()
@@ -47,7 +55,7 @@ abstract class RelevantRealConversion extends RelevantConversion, Conversion {
4755
override Expr getConvertedExpr() { result = this.getExpr() }
4856
}
4957

50-
class UsualArithmeticConversion extends RelevantRealConversion {
58+
class UsualArithmeticConversion extends IntegerPromotionOrUsualArithmeticConversionAsCast {
5159
UsualArithmeticConversion() {
5260
(
5361
// Most binary operations from and to numeric types participate in usual arithmetic conversions
@@ -72,9 +80,11 @@ class UsualArithmeticConversion extends RelevantRealConversion {
7280
override string getKindOfConversion() { result = "Usual arithmetic conversion" }
7381
}
7482

75-
class IntegerPromotion extends RelevantRealConversion {
83+
class IntegerPromotion extends IntegerPromotionOrUsualArithmeticConversionAsCast {
7684
IntegerPromotion() {
77-
// Exclude integer promotions combined with usual arithmetic conversions, which are handled separately
85+
// In the case where a conversion involves both an integer promotion and a usual arithmetic conversion
86+
// we only get a single `Conversion` which combines both. According to the rule, only the "final" type
87+
// should be consider, so we handle these combined conversions as `UsualArithmeticConversion`s instead.
7888
not this instanceof UsualArithmeticConversion and
7989
// Only consider cases where the integer promotion is the last conversion applied
8090
exists(Expr e | e.getFullyConverted() = this) and
@@ -94,7 +104,7 @@ class IntegerPromotion extends RelevantRealConversion {
94104
override string getKindOfConversion() { result = "Integer promotion" }
95105
}
96106

97-
class ImpliedUsualArithmeticConversion extends RelevantConversion {
107+
class ImpliedUsualArithmeticConversion extends IntegerPromotionOrUsualArithmeticConversion {
98108
NumericType fromType;
99109
NumericType toType;
100110

@@ -128,15 +138,17 @@ class ImpliedUsualArithmeticConversion extends RelevantConversion {
128138
override string getKindOfConversion() { result = "Usual arithmetic conversion" }
129139
}
130140

131-
class ImpliedIntegerPromotion extends RelevantConversion {
141+
class ImpliedIntegerPromotion extends IntegerPromotionOrUsualArithmeticConversion {
132142
NumericType fromType;
133143

134144
ImpliedIntegerPromotion() {
135145
(
136146
exists(AssignLShiftExpr aop | aop.getLValue() = this) or
137147
exists(AssignRShiftExpr aop | aop.getLValue() = this)
138148
) and
139-
// Only consider integer promotions from MISRA C++ "numeric types" as per the rule
149+
// The rule applies to integer promotions from and to MISRA C++ numeric types
150+
// However, you cannot have an integer promotion on a float, so we restrict
151+
// this to integral types only
140152
fromType = this.getType() and
141153
fromType.getTypeCategory() = Integral() and
142154
// If the size is less than int, then it is an implied integer promotion
@@ -184,7 +196,9 @@ class ImpliedIntegerPromotion extends RelevantConversion {
184196
override string getKindOfConversion() { result = "Integer promotion" }
185197
}
186198

187-
from Expr e, RelevantConversion c, NumericType fromType, NumericType toType, string changeType
199+
from
200+
Expr e, IntegerPromotionOrUsualArithmeticConversion c, NumericType fromType, NumericType toType,
201+
string changeType
188202
where
189203
not isExcluded(e, ConversionsPackage::noSignednessChangeFromPromotionQuery()) and
190204
c.getConvertedExpr() = e and

0 commit comments

Comments
 (0)