Skip to content

Commit 37d59bb

Browse files
committed
Update DIR-4-6 to include size check for typedef
1 parent 09eab92 commit 37d59bb

File tree

3 files changed

+50
-35
lines changed

3 files changed

+50
-35
lines changed

c/misra/src/rules/DIR-4-6/PlainNumericalTypeUsedOverExplicitTypedef.ql

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,23 @@ predicate forbiddenBuiltinNumericUsedInDecl(Variable var, string message) {
3737
message = "The type " + var.getType() + " is not a fixed-width numeric type."
3838
}
3939

40-
predicate forbiddenTypedef(TypedefType typedef, string message) {
41-
typedef.getBaseType() instanceof BuiltInNumericType and
42-
not typedef.getName().regexpMatch("u?(int|float)(4|8|16|32|64|128)_t") and
43-
message = "The type " + typedef.getName() + " is not an alias to a fixed-width numeric type."
40+
// TODO: add some inline comments
41+
predicate forbiddenTypedef(CTypedefType typedef, string message) {
42+
/* If the typedef's name contains an explicit size */
43+
(
44+
if typedef.getName().regexpMatch("u?(int|float)(4|8|16|32|64|128)_t")
45+
then (
46+
/* Then the actual type size should match. */
47+
not typedef.getSize() * 8 =
48+
// times 8 because getSize() gets the size in bytes
49+
typedef.getName().regexpCapture("u?(int|float)(4|8|16|32|64|128)_t", 2).toInt() and
50+
message = "The typedef type " + typedef.getName() + " does not have its indicated size."
51+
) else (
52+
/* Otherwise, the aliased type itself should have an explicit size in its name. */
53+
not typedef.getBaseType().getName().regexpMatch("u?(int|float)(4|8|16|32|64|128)_t") and
54+
message = "The type " + typedef.getName() + " is not an alias to a fixed-width numeric type."
55+
)
56+
)
4457
}
4558

4659
from Element elem, string message

c/misra/test/rules/DIR-4-6/PlainNumericalTypeUsedOverExplicitTypedef.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
| test.c:14:5:14:10 | int4_t | The typedef type int4_t does not have its indicated size. |
2+
| test.c:16:5:16:11 | uint4_t | The typedef type uint4_t does not have its indicated size. |
13
| test.c:27:5:27:26 | _astronomical_number_t | The type _astronomical_number_t is not an alias to a fixed-width numeric type. |
24
| test.c:34:15:34:16 | c2 | The type signed char is not a fixed-width numeric type. |
35
| test.c:35:17:35:18 | c3 | The type unsigned char is not a fixed-width numeric type. |

c/misra/test/rules/DIR-4-6/test.c

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
typedef signed char int8_t; // COMPLIANT: exception, typedefs are permitted
2-
typedef unsigned char uint8_t; // COMPLIANT: exception, typedefs are permitted
1+
typedef signed char int8_t; // COMPLIANT: exception, typedefs are permitted
2+
typedef unsigned char uint8_t; // COMPLIANT: exception, typedefs are permitted
33

44
typedef signed short int16_t; // COMPLIANT: exception, typedefs are permitted
55
typedef unsigned short uint16_t; // COMPLIANT: exception, typedefs are permitted
66

7-
typedef signed int int32_t; // COMPLIANT: exception, typedefs are permitted
8-
typedef unsigned int uint32_t; // COMPLIANT: exception, typedefs are permitted
7+
typedef signed int int32_t; // COMPLIANT: exception, typedefs are permitted
8+
typedef unsigned int uint32_t; // COMPLIANT: exception, typedefs are permitted
99

10-
typedef signed long int64_t; // COMPLIANT: exception, typedefs are permitted
11-
typedef unsigned long uint64_t; // COMPLIANT: exception, typedefs are permitted
10+
typedef signed long int64_t; // COMPLIANT: exception, typedefs are permitted
11+
typedef unsigned long uint64_t; // COMPLIANT: exception, typedefs are permitted
1212

1313
typedef signed long long
14-
int128_t; // COMPLIANT: exception, typedefs are permitted
14+
int4_t; // NON_COMPLIANT: typedef does not have its indicated size
1515
typedef unsigned long long
16-
uint128_t; // COMPLIANT: exception, typedefs are permitted
16+
uint4_t; // NON_COMPLIANT: typedef does not have its indicated size
1717

1818
typedef float float32_t; // COMPLIANT: exception, typedefs are permitted
1919
typedef double float64_t; // COMPLIANT: exception, typedefs are permitted
@@ -28,38 +28,38 @@ typedef int
2828

2929
int // COMPLIANT: exception, main's return type can be plain int
3030
main(int argc, // COMPLIANT: exception, argc's type can be plain int
31-
char *argv[]) { // COMPLIANT: char is not a basic numeric type
31+
char *argv[]) { // COMPLIANT: char is not a basic numeric type
3232

33-
char c1 = 1; // COMPLIANT: char is not a basic numeric type
34-
signed char c2 = 1; // NON_COMPLIANT: use typedef int8_t
35-
unsigned char c3 = 1; // NON_COMPLIANT: use typedef uint8_t
36-
int8_t c4 = 1; // COMPLIANT: typedef used instead
33+
char c1 = 1; // COMPLIANT: char is not a basic numeric type
34+
signed char c2 = 1; // NON_COMPLIANT: use typedef int8_t
35+
unsigned char c3 = 1; // NON_COMPLIANT: use typedef uint8_t
36+
int8_t c4 = 1; // COMPLIANT: typedef used instead
3737

38-
short s1 = 1; // NON_COMPLIANT: short is a basic numeric type
39-
signed short s2 = 1; // NON_COMPLIANT: use typedef int16_t
40-
unsigned short s3 = 1; // NON_COMPLIANT: use typedef uint16_t
41-
int16_t s4 = 1; // COMPLIANT: typedef used instead
38+
short s1 = 1; // NON_COMPLIANT: short is a basic numeric type
39+
signed short s2 = 1; // NON_COMPLIANT: use typedef int16_t
40+
unsigned short s3 = 1; // NON_COMPLIANT: use typedef uint16_t
41+
int16_t s4 = 1; // COMPLIANT: typedef used instead
4242

43-
int i1 = 1; // NON_COMPLIANT: int is a basic numeric type
44-
signed int i2 = 1; // NON_COMPLIANT: use typedef int32_t
45-
unsigned int i3 = 1; // NON_COMPLIANT: use typedef uint32_t
46-
int32_t i4 = 1; // COMPLIANT: typedef used instead
43+
int i1 = 1; // NON_COMPLIANT: int is a basic numeric type
44+
signed int i2 = 1; // NON_COMPLIANT: use typedef int32_t
45+
unsigned int i3 = 1; // NON_COMPLIANT: use typedef uint32_t
46+
int32_t i4 = 1; // COMPLIANT: typedef used instead
4747

48-
long l1 = 1; // NON_COMPLIANT: int is a basic numeric type
49-
signed long l2 = 1; // NON_COMPLIANT: use typedef int64_t
50-
unsigned long l3 = 1; // NON_COMPLIANT: use typedef uint64_t
51-
int64_t l4 = 1; // COMPLIANT: typedef used instead
48+
long l1 = 1; // NON_COMPLIANT: int is a basic numeric type
49+
signed long l2 = 1; // NON_COMPLIANT: use typedef int64_t
50+
unsigned long l3 = 1; // NON_COMPLIANT: use typedef uint64_t
51+
int64_t l4 = 1; // COMPLIANT: typedef used instead
5252

5353
long long ll1 = 1; // NON_COMPLIANT: int is a basic numeric type
54-
signed long long ll2 = 1; // NON_COMPLIANT: use typedef int128_t
55-
unsigned long long ll3 = 1; // NON_COMPLIANT: use typedef uint128_t
56-
int128_t ll4 = 1; // COMPLIANT: typedef used instead
54+
signed long long ll2 = 1; // NON_COMPLIANT: use typedef int64_t
55+
unsigned long long ll3 = 1; // NON_COMPLIANT: use typedef uint64_t
56+
int64_t ll4 = 1; // COMPLIANT: typedef used instead
5757

5858
float f1 = 1; // NON_COMPLIANT: float is a basic numeric type, use a typedef
59-
float32_t f2 = 1; // COMPLIANT: typedef used instead
59+
float32_t f2 = 1; // COMPLIANT: typedef used instead
6060

61-
double d1 = 1; // NON_COMPLIANT: int is a basic numeric type
62-
float64_t d2 = 1; // COMPLIANT: typedef used instead
61+
double d1 = 1; // NON_COMPLIANT: int is a basic numeric type
62+
float64_t d2 = 1; // COMPLIANT: typedef used instead
6363

6464
long double ld1 = 1; // NON_COMPLIANT: int is a basic numeric type
6565
float128_t ld2 = 1; // COMPLIANT: typedef used instead

0 commit comments

Comments
 (0)