Skip to content

Commit c727f2f

Browse files
Import MEM51-CPP, mismatched new/delete[]/malloc/free is UB
1 parent d7d4769 commit c727f2f

File tree

13 files changed

+116
-17
lines changed

13 files changed

+116
-17
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `MEM51-CPP` - `ProperlyDeallocateDynamicallyAllocatedResources.ql`:
2+
- Refactored query logic into a shared library (`ProperlyDeallocateDynamicallyAllocatedResourcesShared.qll`) to enable reuse by MISRA C++ `RULE-4-1-3`. The query logic is unchanged and no visible changes to results or performance are expected.

cpp/cert/src/rules/MEM51-CPP/ProperlyDeallocateDynamicallyAllocatedResources.ql

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,14 @@
1919

2020
import cpp
2121
import codingstandards.cpp.cert
22-
import codingstandards.cpp.Allocations
22+
import codingstandards.cpp.rules.properlydeallocatedynamicallyallocatedresourcesshared.ProperlyDeallocateDynamicallyAllocatedResourcesShared
2323

24-
predicate matching(string allocKind, string deleteKind) {
25-
allocKind = "new" and deleteKind = "delete"
26-
or
27-
allocKind = "new[]" and deleteKind = "delete[]"
28-
or
29-
allocKind = "malloc" and deleteKind = "free"
24+
module ProperlyDeallocateDynamicallyAllocatedResourcesConfig implements
25+
ProperlyDeallocateDynamicallyAllocatedResourcesSharedConfigSig
26+
{
27+
Query getQuery() {
28+
result = AllocationsPackage::properlyDeallocateDynamicallyAllocatedResourcesQuery()
29+
}
3030
}
3131

32-
from Expr alloc, Expr free, Expr freed, string allocKind, string deleteKind
33-
where
34-
not isExcluded(freed, AllocationsPackage::properlyDeallocateDynamicallyAllocatedResourcesQuery()) and
35-
allocReaches(freed, alloc, allocKind) and
36-
freeExprOrIndirect(free, freed, deleteKind) and
37-
not matching(allocKind, deleteKind)
38-
select free, "Memory allocated with $@ but deleted with " + deleteKind + ".", alloc, allocKind
32+
import ProperlyDeallocateDynamicallyAllocatedResourcesShared<ProperlyDeallocateDynamicallyAllocatedResourcesConfig>

cpp/cert/test/rules/MEM51-CPP/ProperlyDeallocateDynamicallyAllocatedResources.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp/common/test/rules/properlydeallocatedynamicallyallocatedresourcesshared/ProperlyDeallocateDynamicallyAllocatedResourcesShared.ql

cpp/common/src/codingstandards/cpp/exclusions/cpp/Undefined.qll

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ newtype UndefinedQuery =
88
TCriticalUnspecifiedBehaviorQuery() or
99
TUndefinedBehaviorAuditQuery() or
1010
TCriticalUnspecifiedBehaviorAuditQuery() or
11-
TPossibleDataRaceBetweenThreadsQuery()
11+
TPossibleDataRaceBetweenThreadsQuery() or
12+
TDeallocationTypeMismatchQuery()
1213

1314
predicate isUndefinedQueryMetadata(Query query, string queryId, string ruleId, string category) {
1415
query =
@@ -55,6 +56,15 @@ predicate isUndefinedQueryMetadata(Query query, string queryId, string ruleId, s
5556
"cpp/misra/possible-data-race-between-threads" and
5657
ruleId = "RULE-4-1-3" and
5758
category = "required"
59+
or
60+
query =
61+
// `Query` instance for the `deallocationTypeMismatch` query
62+
UndefinedPackage::deallocationTypeMismatchQuery() and
63+
queryId =
64+
// `@id` for the `deallocationTypeMismatch` query
65+
"cpp/misra/deallocation-type-mismatch" and
66+
ruleId = "RULE-4-1-3" and
67+
category = "required"
5868
}
5969

6070
module UndefinedPackage {
@@ -92,4 +102,11 @@ module UndefinedPackage {
92102
// `Query` type for `possibleDataRaceBetweenThreads` query
93103
TQueryCPP(TUndefinedPackageQuery(TPossibleDataRaceBetweenThreadsQuery()))
94104
}
105+
106+
Query deallocationTypeMismatchQuery() {
107+
//autogenerate `Query` type
108+
result =
109+
// `Query` type for `deallocationTypeMismatch` query
110+
TQueryCPP(TUndefinedPackageQuery(TDeallocationTypeMismatchQuery()))
111+
}
95112
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Provides a configurable module ProperlyDeallocateDynamicallyAllocatedResourcesShared with a
3+
* `problems` predicate for the following issue:
4+
* Deallocation functions should only be called on nullptr or a pointer returned by the
5+
* corresponding allocation function, that hasn't already been deallocated.
6+
*/
7+
8+
import cpp
9+
import codingstandards.cpp.Customizations
10+
import codingstandards.cpp.Exclusions
11+
import codingstandards.cpp.Allocations
12+
13+
signature module ProperlyDeallocateDynamicallyAllocatedResourcesSharedConfigSig {
14+
Query getQuery();
15+
}
16+
17+
module ProperlyDeallocateDynamicallyAllocatedResourcesShared<
18+
ProperlyDeallocateDynamicallyAllocatedResourcesSharedConfigSig Config>
19+
{
20+
private predicate matching(string allocKind, string deleteKind) {
21+
allocKind = "new" and deleteKind = "delete"
22+
or
23+
allocKind = "new[]" and deleteKind = "delete[]"
24+
or
25+
allocKind = "malloc" and deleteKind = "free"
26+
}
27+
28+
query predicate problems(Expr free, string message, Expr alloc, string allocKind) {
29+
exists(Expr freed, string deleteKind |
30+
not isExcluded(freed, Config::getQuery()) and
31+
allocReaches(freed, alloc, allocKind) and
32+
freeExprOrIndirect(free, freed, deleteKind) and
33+
not matching(allocKind, deleteKind) and
34+
message = "Memory allocated with $@ but deleted with " + deleteKind + "."
35+
)
36+
}
37+
}

cpp/cert/test/rules/MEM51-CPP/ProperlyDeallocateDynamicallyAllocatedResources.expected renamed to cpp/common/test/rules/properlydeallocatedynamicallyallocatedresourcesshared/ProperlyDeallocateDynamicallyAllocatedResourcesShared.expected

File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.properlydeallocatedynamicallyallocatedresourcesshared.ProperlyDeallocateDynamicallyAllocatedResourcesShared
3+
4+
module TestFileConfig implements ProperlyDeallocateDynamicallyAllocatedResourcesSharedConfigSig {
5+
Query getQuery() { result instanceof TestQuery }
6+
}
7+
8+
import ProperlyDeallocateDynamicallyAllocatedResourcesShared<TestFileConfig>

cpp/cert/test/rules/MEM51-CPP/test.cpp renamed to cpp/common/test/rules/properlydeallocatedynamicallyallocatedresourcesshared/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ void test_malloc() {
3333

3434
int *i3 = (int *)malloc(sizeof(int));
3535
free(i3); // COMPLIANT
36-
}
36+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @id cpp/misra/deallocation-type-mismatch
3+
* @name RULE-4-1-3: Deallocation type mismatch leads to undefined behavior
4+
* @description Using a deallocation function that does not match the allocation function results in
5+
* undefined behavior.
6+
* @kind problem
7+
* @precision medium
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-4-1-3
10+
* correctness
11+
* scope/system
12+
* external/misra/enforcement/undecidable
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.cpp.misra
18+
import codingstandards.cpp.rules.properlydeallocatedynamicallyallocatedresourcesshared.ProperlyDeallocateDynamicallyAllocatedResourcesShared
19+
20+
module DeallocationTypeMismatchConfig implements
21+
ProperlyDeallocateDynamicallyAllocatedResourcesSharedConfigSig
22+
{
23+
Query getQuery() { result = UndefinedPackage::deallocationTypeMismatchQuery() }
24+
}
25+
26+
import ProperlyDeallocateDynamicallyAllocatedResourcesShared<DeallocationTypeMismatchConfig>

0 commit comments

Comments
 (0)