Skip to content

Commit 21cf410

Browse files
committed
CanonicalTypes: refactor library
- Create new shared library for canonical integer types - Implement `isMinimal` case to handle instances where multiple canonical types have the same size (for example `long` and `long long` on some platforms). - Create a new CanonicalIntegerNumericType for representing the concept of MISRA numeric canonical types. Set isMinimal() in the charpred to automatically filter out multiple canonical types for the same size and signedness.
1 parent 2c0d06b commit 21cf410

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import cpp
2+
3+
/**
4+
* One of the 10 canonical integer types, which are the standard integer types.
5+
*/
6+
class CanonicalIntegralType extends IntegralType {
7+
CanonicalIntegralType() { this = this.getCanonicalArithmeticType() }
8+
9+
/**
10+
* Holds if this is the canonical integer type with the shortest name for its size.
11+
*/
12+
predicate isMinimal() {
13+
not exists(CanonicalIntegralType other |
14+
other.getSize() = this.getSize() and
15+
other.getName().length() < this.getName().length()
16+
)
17+
}
18+
}

cpp/misra/src/codingstandards/cpp/misra/BuiltInTypeRules.qll

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import cpp
66
import codingstandards.cpp.misra
77
import codingstandards.cpp.Call
88
import codingstandards.cpp.Type
9+
import codingstandards.cpp.types.CanonicalTypes
910

1011
/**
1112
* A MISRA C++ 2023 type category.
@@ -142,10 +143,18 @@ predicate isSignedType(NumericType t) { t.getSignedness() = Signed() }
142143
predicate isUnsignedType(NumericType t) { t.getSignedness() = Unsigned() }
143144

144145
/**
145-
* One of the 10 canonical integer types, which are the standard integer types.
146+
* A canonical integer type for each unique size and signedness combination.
147+
*
148+
* Where multiple canonical arithmetic types exist for a given size/signedness combination, we
149+
* prefer the type with the shortest name.
146150
*/
147-
class CanonicalIntegerType extends NumericType, IntegralType {
148-
CanonicalIntegerType() { this = this.getCanonicalArithmeticType() }
151+
class CanonicalIntegerNumericType extends NumericType, CanonicalIntegralType {
152+
CanonicalIntegerNumericType() {
153+
// Where multiple types exist with the same size and signedness, prefer shorter names - mainly
154+
// to disambiguate between `unsigned long` and `unsigned long long` on platforms where they
155+
// are the same size
156+
this.isMinimal()
157+
}
149158
}
150159

151160
predicate isAssignment(Expr source, Type targetType, string context) {
@@ -264,24 +273,18 @@ predicate isPreConversionAssignment(Expr source, Type targetType, string context
264273
*
265274
* The type is determined by the signedness of the bit field and the number of bits.
266275
*/
267-
CanonicalIntegerType getBitFieldType(BitField bf) {
276+
CanonicalIntegerNumericType getBitFieldType(BitField bf) {
268277
exists(NumericType bitfieldActualType |
269278
bitfieldActualType = bf.getType() and
270279
// Integral type with the same signedness as the bit field, and big enough to hold the bit field value
271280
result.getSignedness() = bitfieldActualType.getSignedness() and
272281
result.getSize() * 8 >= bf.getNumBits() and
273282
// No smaller integral type can hold the bit field value
274-
not exists(CanonicalIntegerType other |
283+
not exists(CanonicalIntegerNumericType other |
275284
other.getSize() * 8 >= bf.getNumBits() and
276285
other.getSignedness() = result.getSignedness()
277286
|
278287
other.getSize() < result.getRealSize()
279-
or
280-
// Where multiple types exist with the same size and signedness, prefer shorter names - mainly
281-
// to disambiguate between `unsigned long` and `unsigned long long` on platforms where they
282-
// are the same size
283-
other.getSize() = result.getRealSize() and
284-
other.getName().length() < result.getName().length()
285288
)
286289
)
287290
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ class ImpliedIntegerPromotion extends RelevantConversion {
145145

146146
override NumericType getFromType() { result = fromType }
147147

148-
override CanonicalIntegerType getToType() {
148+
override CanonicalIntegerNumericType getToType() {
149149
// Only report the canonical type - e.g. `int` not `signed int`
150150
if result instanceof Char16Type or result instanceof Char32Type or result instanceof Wchar_t
151151
then

0 commit comments

Comments
 (0)