Skip to content

Commit 3f73b26

Browse files
authored
Merge pull request #744 from github/lcartey/rule-11-3-specified-void-type
`RULE-11-*`: Improve detection of const void pointers
2 parents 0730c2d + 6e93025 commit 3f73b26

File tree

10 files changed

+39
-7
lines changed

10 files changed

+39
-7
lines changed

c/misra/src/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import codingstandards.cpp.Pointers
1919
from Cast cast, VoidPointerType type, PointerToObjectType newType
2020
where
2121
not isExcluded(cast, Pointers1Package::conversionFromPointerToVoidIntoPointerToObjectQuery()) and
22-
type = cast.getExpr().getUnderlyingType() and
22+
type = cast.getExpr().getUnspecifiedType() and
2323
newType = cast.getUnderlyingType() and
2424
not isNullPointerConstant(cast.getExpr())
2525
select cast,

c/misra/test/rules/RULE-11-3/CastBetweenObjectPointerAndDifferentObjectType.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22
| test.c:14:8:14:9 | (int *)... | Cast performed between a pointer to object type (char) and a pointer to a different object type (int). |
33
| test.c:15:8:15:25 | (int *)... | Cast performed between a pointer to object type (short) and a pointer to a different object type (int). |
44
| test.c:15:15:15:25 | (short *)... | Cast performed between a pointer to object type (char) and a pointer to a different object type (short). |
5+
| test.c:20:3:20:17 | (const int *)... | Cast performed between a pointer to object type (char) and a pointer to a different object type (const int). |
6+
| test.c:21:3:21:16 | (int *)... | Cast performed between a pointer to object type (char) and a pointer to a different object type (int). |
7+
| test.c:22:20:22:21 | (int *)... | Cast performed between a pointer to object type (char) and a pointer to a different object type (int). |
8+
| test.c:23:3:23:18 | (long long *)... | Cast performed between a pointer to object type (int) and a pointer to a different object type (long long). |

c/misra/test/rules/RULE-11-3/test.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,12 @@ void f1(void) {
1313
int *v8 = (int *)0; // COMPLIANT
1414
v8 = v2; // NON_COMPLIANT
1515
v8 = (int *)(short *)v2; // NON_COMPLIANT
16+
(const void *)v1; // COMPLIANT
17+
const void *v9 = v1; // COMPLIANT
18+
(int *)v9; // COMPLIANT - cast from void*
19+
(const void *)v2; // COMPLIANT
20+
(const int *)v2; // NON_COMPLIANT
21+
(int *const)v2; // NON_COMPLIANT
22+
int *const v10 = v2; // NON_COMPLIANT
23+
(long long *)v10; // NON_COMPLIANT
1624
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
| test.c:6:21:6:37 | (unsigned int)... | Cast from pointer to object type 'unsigned int *' to integer type 'unsigned int'. | test.c:6:21:6:37 | (unsigned int)... | |
22
| test.c:8:8:8:24 | (unsigned int)... | Cast from pointer to object type 'unsigned int *' to integer type 'unsigned int'. | test.c:8:8:8:24 | (unsigned int)... | |
33
| test.c:12:22:12:39 | (unsigned int *)... | Cast from integer type 'unsigned int' to pointer to object type 'unsigned int *'. | test.c:12:22:12:39 | (unsigned int *)... | |
4-
| test.c:15:1:15:24 | #define FOO (int *)0x200 | Cast from integer type 'int' to pointer to object type 'int *'. | test.c:15:1:15:24 | #define FOO (int *)0x200 | |
5-
| test.c:23:3:23:22 | (int *)... | Cast from integer type 'int' to pointer to object type 'int *' from expansion of macro $@. | test.c:17:1:17:34 | #define FOO_FUNCTIONAL(x) (int *)x | FOO_FUNCTIONAL |
6-
| test.c:24:14:24:25 | (int *)... | Cast from integer type 'int' to pointer to object type 'int *' from expansion of macro $@. | test.c:18:1:18:23 | #define FOO_INSERT(x) x | FOO_INSERT |
4+
| test.c:18:1:18:24 | #define FOO (int *)0x200 | Cast from integer type 'int' to pointer to object type 'int *'. | test.c:18:1:18:24 | #define FOO (int *)0x200 | |
5+
| test.c:26:3:26:22 | (int *)... | Cast from integer type 'int' to pointer to object type 'int *' from expansion of macro $@. | test.c:20:1:20:34 | #define FOO_FUNCTIONAL(x) (int *)x | FOO_FUNCTIONAL |
6+
| test.c:27:14:27:25 | (int *)... | Cast from integer type 'int' to pointer to object type 'int *' from expansion of macro $@. | test.c:21:1:21:23 | #define FOO_INSERT(x) x | FOO_INSERT |

c/misra/test/rules/RULE-11-4/test.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ void f1(void) {
1010
unsigned int *v4 = 0; // COMPLIANT
1111
unsigned int *v5 = NULL; // COMPLIANT
1212
unsigned int *v6 = (unsigned int *)v2; // NON_COMPLIANT
13+
const void *v7 = 0;
14+
(unsigned int)v7; // COMPLIANT - cast const void to int
15+
(const void *)v1; // COMPLIANT - casting int to const void
1316
}
1417

1518
#define FOO (int *)0x200 // NON_COMPLIANT
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
| test.c:6:13:6:21 | (int *)... | Cast performed from a void pointer into a pointer to an object (int *). |
2+
| test.c:11:3:11:11 | (int *)... | Cast performed from a void pointer into a pointer to an object (int *). |

c/misra/test/rules/RULE-11-5/test.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,8 @@ void f1(void) {
77
v2 = NULL; // COMPLIANT
88
void *v3 = (void *)v1; // COMPLIANT
99
v3 = (void *)v2; // COMPLIANT
10+
const void *v4 = 0;
11+
(int *)v4; // NON_COMPLIANT - const in type is irrelevant
12+
(const void *)v1; // COMPLIANT - casting is from void to void, const addition
13+
// should be irrelevant
1014
}

c/misra/test/rules/RULE-11-7/test.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,12 @@ void f1(void) {
77
float v4 = (float)(bool)v1; // NON_COMPLIANT
88
v1 = (int *)v2; // NON_COMPLIANT
99
v4 = (float)v3; // COMPLIANT
10+
void *v5 = 0;
11+
const void *v6 = 0;
12+
// void pointers (regardless of specifier) are not pointers to object, so all
13+
// these examples are compliant according to this rule
14+
(bool)v5; // COMPLIANT
15+
(bool)v6; // COMPLIANT
16+
(void *)v2; // COMPLIANT
17+
(const void *)v2; // COMPLIANT
1018
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- `RULE-11-3`, `RULE-11-4`, `RULE-11-5`, `RULE-11-7` - `CastBetweenObjectPointerAndDifferentObjectType.ql`, `ConversionBetweenPointerToObjectAndIntegerType.ql`, `ConversionFromPointerToVoidIntoPointerToObject.ql`, `CastBetweenPointerToObjectAndNonIntArithmeticType.ql`:
2+
- Removed false positives where casts involved a specified void type pointer, e.g. `const void*`, which should not be considered as a pointer to object.
3+
- `RULE-11-5` - `ConversionFromPointerToVoidIntoPointerToObject.ql`:
4+
- Addressed false negatives where the pointer-to-void was specified.

cpp/common/src/codingstandards/cpp/Pointers.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ predicate isCastNullPointerConstant(Cast c) {
8080
class PointerToObjectType extends PointerType {
8181
PointerToObjectType() {
8282
not (
83-
this.getUnderlyingType() instanceof FunctionPointerType or
84-
this.getUnderlyingType() instanceof VoidPointerType or
85-
this.getBaseType().getUnderlyingType() instanceof IncompleteType
83+
this.getUnspecifiedType() instanceof FunctionPointerType or
84+
this.getUnspecifiedType() instanceof VoidPointerType or
85+
this.getBaseType().getUnspecifiedType() instanceof IncompleteType
8686
)
8787
}
8888
}

0 commit comments

Comments
 (0)