Skip to content

RULE-11-*: Improve detection of const void pointers #744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import codingstandards.cpp.Pointers
from Cast cast, VoidPointerType type, PointerToObjectType newType
where
not isExcluded(cast, Pointers1Package::conversionFromPointerToVoidIntoPointerToObjectQuery()) and
type = cast.getExpr().getUnderlyingType() and
type = cast.getExpr().getUnspecifiedType() and
newType = cast.getUnderlyingType() and
not isNullPointerConstant(cast.getExpr())
select cast,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
| 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). |
| 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). |
| 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). |
| 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). |
| 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). |
| 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). |
| 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). |
8 changes: 8 additions & 0 deletions c/misra/test/rules/RULE-11-3/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,12 @@ void f1(void) {
int *v8 = (int *)0; // COMPLIANT
v8 = v2; // NON_COMPLIANT
v8 = (int *)(short *)v2; // NON_COMPLIANT
(const void *)v1; // COMPLIANT
const void *v9 = v1; // COMPLIANT
(int *)v9; // COMPLIANT - cast from void*
(const void *)v2; // COMPLIANT
(const int *)v2; // NON_COMPLIANT
(int *const)v2; // NON_COMPLIANT
int *const v10 = v2; // NON_COMPLIANT
(long long *)v10; // NON_COMPLIANT
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
| 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)... | |
| 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)... | |
| 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 *)... | |
| 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 | |
| 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 |
| 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 |
| 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 | |
| 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 |
| 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 |
3 changes: 3 additions & 0 deletions c/misra/test/rules/RULE-11-4/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ void f1(void) {
unsigned int *v4 = 0; // COMPLIANT
unsigned int *v5 = NULL; // COMPLIANT
unsigned int *v6 = (unsigned int *)v2; // NON_COMPLIANT
const void *v7 = 0;
(unsigned int)v7; // COMPLIANT - cast const void to int
(const void *)v1; // COMPLIANT - casting int to const void
}

#define FOO (int *)0x200 // NON_COMPLIANT
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
| test.c:6:13:6:21 | (int *)... | Cast performed from a void pointer into a pointer to an object (int *). |
| test.c:11:3:11:11 | (int *)... | Cast performed from a void pointer into a pointer to an object (int *). |
4 changes: 4 additions & 0 deletions c/misra/test/rules/RULE-11-5/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ void f1(void) {
v2 = NULL; // COMPLIANT
void *v3 = (void *)v1; // COMPLIANT
v3 = (void *)v2; // COMPLIANT
const void *v4 = 0;
(int *)v4; // NON_COMPLIANT - const in type is irrelevant
(const void *)v1; // COMPLIANT - casting is from void to void, const addition
// should be irrelevant
}
8 changes: 8 additions & 0 deletions c/misra/test/rules/RULE-11-7/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,12 @@ void f1(void) {
float v4 = (float)(bool)v1; // NON_COMPLIANT
v1 = (int *)v2; // NON_COMPLIANT
v4 = (float)v3; // COMPLIANT
void *v5 = 0;
const void *v6 = 0;
// void pointers (regardless of specifier) are not pointers to object, so all
// these examples are compliant according to this rule
(bool)v5; // COMPLIANT
(bool)v6; // COMPLIANT
(void *)v2; // COMPLIANT
(const void *)v2; // COMPLIANT
}
4 changes: 4 additions & 0 deletions change_notes/2024-10-11-specifiers-rule-11-misra-c.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- `RULE-11-3`, `RULE-11-4`, `RULE-11-5`, `RULE-11-7` - `CastBetweenObjectPointerAndDifferentObjectType.ql`, `ConversionBetweenPointerToObjectAndIntegerType.ql`, `ConversionFromPointerToVoidIntoPointerToObject.ql`, `CastBetweenPointerToObjectAndNonIntArithmeticType.ql`:
- 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.
- `RULE-11-5` - `ConversionFromPointerToVoidIntoPointerToObject.ql`:
- Addressed false negatives where the pointer-to-void was specified.
6 changes: 3 additions & 3 deletions cpp/common/src/codingstandards/cpp/Pointers.qll
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ predicate isCastNullPointerConstant(Cast c) {
class PointerToObjectType extends PointerType {
PointerToObjectType() {
not (
this.getUnderlyingType() instanceof FunctionPointerType or
this.getUnderlyingType() instanceof VoidPointerType or
this.getBaseType().getUnderlyingType() instanceof IncompleteType
this.getUnspecifiedType() instanceof FunctionPointerType or
this.getUnspecifiedType() instanceof VoidPointerType or
this.getBaseType().getUnspecifiedType() instanceof IncompleteType
)
}
}
Expand Down
Loading