Skip to content

Commit ab43602

Browse files
committed
Add Rule-19-1 and converted M0-2-1 to shared query
1 parent 892fab6 commit ab43602

20 files changed

+263
-55
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:9:3:9:11 | ... = ... | An object $@ assigned to overlapping object $@. | test.c:9:5:9:5 | l | l | test.c:9:11:9:11 | i | i |
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.overlappingobjectassignment.OverlappingObjectAssignment
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <stdint.h>
2+
3+
void f(void) {
4+
union {
5+
int i;
6+
long l;
7+
} u = {0};
8+
9+
u.l = u.i; // NON_COMPLIANT
10+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @id c/misra/object-assigned-to-an-overlapping-object
3+
* @name RULE-19-1: An object shall not be assigned to an overlapping object
4+
* @description An object shall not be assigned to an overlapping object.
5+
* @kind problem
6+
* @precision high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-19-1
9+
* correctness
10+
* external/misra/obligation/mandatory
11+
*/
12+
13+
import cpp
14+
import codingstandards.c.misra
15+
import codingstandards.cpp.rules.overlappingobjectassignment.OverlappingObjectAssignment
16+
17+
class ObjectAssignedToAnOverlappingObjectQuery extends OverlappingObjectAssignmentSharedQuery {
18+
ObjectAssignedToAnOverlappingObjectQuery() {
19+
this = Contracts7Package::objectAssignedToAnOverlappingObjectQuery()
20+
}
21+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/**
2+
* @id c/misra/object-copied-to-an-overlapping-object
3+
* @name RULE-19-1: An object shall not be copied to an overlapping object
4+
* @description An object shall not be copied to an overlapping object.
5+
* @kind problem
6+
* @precision high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-19-1
9+
* correctness
10+
* external/misra/obligation/mandatory
11+
*/
12+
13+
import cpp
14+
import codingstandards.c.misra
15+
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
16+
import semmle.code.cpp.dataflow.DataFlow
17+
18+
/**
19+
* Models calls to memcpy on overlapping objects
20+
*/
21+
class MemcpyCall extends Locatable {
22+
Expr src;
23+
Expr dst;
24+
25+
MemcpyCall() {
26+
this.(MacroInvocation).getMacroName() = "memcpy" and
27+
src = this.(MacroInvocation).getExpr().getChild(1) and
28+
dst = this.(MacroInvocation).getExpr().getChild(0)
29+
or
30+
this.(FunctionCall).getTarget().hasGlobalName("memcpy") and
31+
src = this.(FunctionCall).getArgument(1) and
32+
dst = this.(FunctionCall).getArgument(0)
33+
}
34+
35+
Expr getSrc() { result = src }
36+
37+
Expr getDst() { result = dst }
38+
39+
Expr getBase(Expr e) {
40+
result =
41+
[
42+
e.(VariableAccess), e.(PointerAddExpr).getLeftOperand(),
43+
e.(AddressOfExpr).getOperand().(ArrayExpr).getArrayBase()
44+
]
45+
}
46+
47+
int getOffset(Expr e) {
48+
result =
49+
[
50+
e.(PointerAddExpr).getRightOperand().getValue().toInt(),
51+
e.(AddressOfExpr).getOperand().(ArrayExpr).getArrayOffset().getValue().toInt()
52+
]
53+
or
54+
e instanceof VariableAccess and result = 0
55+
}
56+
57+
// maximum amount of element copied
58+
int getCount() {
59+
result =
60+
upperBound([this.(MacroInvocation).getExpr().getChild(2), this.(FunctionCall).getArgument(2)])
61+
}
62+
63+
// source and destination overlap
64+
predicate overlap() {
65+
globalValueNumber(this.getBase(src)) = globalValueNumber(this.getBase(dst)) and
66+
exists(int dstStart, int dstEnd, int srcStart, int srcEnd |
67+
dstStart = this.getOffset(dst) and
68+
dstEnd = dstStart + this.getCount() - 1 and
69+
srcStart = this.getOffset(src) and
70+
srcEnd = srcStart + this.getCount() - 1 and
71+
(
72+
srcStart >= dstStart and srcEnd <= dstEnd
73+
or
74+
srcStart <= dstStart and srcEnd > dstStart
75+
or
76+
srcStart < dstEnd and srcEnd >= dstStart
77+
) and
78+
// Exception 1: exact overlap and compatible type
79+
not (
80+
srcStart = dstStart and
81+
srcEnd = dstEnd and
82+
this.getBase(src).getUnspecifiedType() = this.getBase(dst).getUnspecifiedType()
83+
)
84+
)
85+
}
86+
}
87+
88+
from MemcpyCall memcpy
89+
where
90+
not isExcluded(memcpy, Contracts7Package::objectCopiedToAnOverlappingObjectQuery()) and
91+
memcpy.overlap()
92+
select memcpy, "The object to copy $@ overlaps the object to copy $@.", memcpy.getSrc(), "from",
93+
memcpy.getDst(), "to"

c/misra/test/rules/RULE-12-2/test.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ void f1() {
2121
ul << 64; // NON_COMPLIANT
2222

2323
// 1UL essential type is essentially unsigned char
24-
1UL << 7; // COMPLIANT
25-
1UL << 8; // NON_COMPLIANT
26-
1UL << 64; // NON_COMPLIANT
24+
1UL << 7; // COMPLIANT
25+
1UL << 8; // NON_COMPLIANT
26+
1UL << 64; // NON_COMPLIANT
2727

2828
// ULONG_MAX essential type is essentially unsigned long
2929
ULONG_MAX << 8; // COMPLIANT
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/overlappingobjectassignment/OverlappingObjectAssignment.ql
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.c:5:3:5:8 | call to memcpy | The object to copy $@ overlaps the object to copy $@. | test.c:5:17:5:21 | & ... | from | test.c:5:10:5:14 | & ... | to |
2+
| test.c:7:3:7:8 | call to memcpy | The object to copy $@ overlaps the object to copy $@. | test.c:7:17:7:21 | & ... | from | test.c:7:10:7:14 | & ... | to |
3+
| test.c:8:3:8:8 | call to memcpy | The object to copy $@ overlaps the object to copy $@. | test.c:8:17:8:17 | o | from | test.c:8:10:8:14 | ... + ... | to |
4+
| test.c:10:3:10:8 | call to memcpy | The object to copy $@ overlaps the object to copy $@. | test.c:10:17:10:21 | ... + ... | from | test.c:10:10:10:14 | ... + ... | to |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-19-1/ObjectCopiedToAnOverlappingObject.ql

c/misra/test/rules/RULE-19-1/test.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <string.h>
2+
3+
int o[10];
4+
void g(void) {
5+
memcpy(&o[1], &o[0], 2); // NON_COMPLIANT
6+
memcpy(&o[2], &o[0], 2); // COMPLIANT
7+
memcpy(&o[2], &o[1], 2); // NON_COMPLIANT
8+
memcpy(o + 1, o, 2); // NON_COMPLIANT
9+
memcpy(o + 2, o, 2); // COMPLIANT
10+
memcpy(o + 2, o + 1, 2); // NON_COMPLIANT
11+
12+
// Exception 1
13+
int *p = &o[0];
14+
int *q = &o[0];
15+
16+
*p = *q; // COMPLIANT
17+
memcpy(&o[0], &o[0], 2); // COMPLIANT
18+
memcpy(o, o, 2); // COMPLIANT
19+
20+
// Exception 2
21+
memmove(&o[1], &o[0], 2u * sizeof(o[0])); // COMPLIANT
22+
}

0 commit comments

Comments
 (0)