@@ -17,7 +17,13 @@ import cpp
1717import codingstandards.cpp.misra
1818import 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
188202where
189203 not isExcluded ( e , ConversionsPackage:: noSignednessChangeFromPromotionQuery ( ) ) and
190204 c .getConvertedExpr ( ) = e and
0 commit comments