Skip to content

Commit b5bc639

Browse files
committed
Remove shared implementation
1 parent c7d50af commit b5bc639

15 files changed

+101
-45
lines changed

c/common/test/rules/overlappingobjectassignment/OverlappingObjectAssignment.expected

Lines changed: 0 additions & 1 deletion
This file was deleted.

c/common/test/rules/overlappingobjectassignment/OverlappingObjectAssignment.ql

Lines changed: 0 additions & 2 deletions
This file was deleted.

c/common/test/rules/overlappingobjectassignment/test.c

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @id c/misra/object-assigned-to-an-overlapping-object
33
* @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.
4+
* @description An object shall not be copied or assigned to an overlapping object.
55
* @kind problem
66
* @precision high
77
* @problem.severity error
@@ -12,10 +12,43 @@
1212

1313
import cpp
1414
import codingstandards.c.misra
15-
import codingstandards.cpp.rules.overlappingobjectassignment.OverlappingObjectAssignment
15+
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1616

17-
class ObjectAssignedToAnOverlappingObjectQuery extends OverlappingObjectAssignmentSharedQuery {
18-
ObjectAssignedToAnOverlappingObjectQuery() {
19-
this = Contracts7Package::objectAssignedToAnOverlappingObjectQuery()
20-
}
17+
VariableAccess getAQualifier(VariableAccess va) { result = va.getQualifier+() }
18+
19+
int getAccessByteOffset(FieldAccess fa) {
20+
not fa.getQualifier() instanceof FieldAccess and result = fa.getTarget().getByteOffset()
21+
or
22+
result = fa.getTarget().getByteOffset() + getAccessByteOffset(fa.getQualifier())
23+
}
24+
25+
predicate overlaps(FieldAccess fa1, FieldAccess fa2) {
26+
exists(int startfa1, int endfa1, int startfa2, int endfa2 |
27+
startfa1 = getAccessByteOffset(fa1) and
28+
endfa1 = startfa1 + fa1.getTarget().getType().getSize() - 1 and
29+
startfa2 = getAccessByteOffset(fa2) and
30+
endfa2 = startfa2 + fa2.getTarget().getType().getSize() - 1
31+
|
32+
startfa1 = startfa2 and endfa1 = endfa2
33+
or
34+
startfa1 > startfa2 and endfa1 < endfa2
35+
or
36+
startfa1 < startfa2 and endfa1 < endfa2 and endfa1 > startfa2
37+
or
38+
startfa1 > startfa2 and endfa1 > endfa2 and startfa1 < endfa2
39+
)
2140
}
41+
42+
from AssignExpr assignExpr, Expr lhs, Expr rhs, ValueFieldAccess valuelhs, ValueFieldAccess valuerhs
43+
where
44+
not isExcluded(assignExpr, Contracts7Package::objectAssignedToAnOverlappingObjectQuery()) and
45+
lhs.getType() instanceof Union and
46+
rhs.getType() instanceof Union and
47+
lhs = getAQualifier(assignExpr.getLValue()) and
48+
rhs = getAQualifier(assignExpr.getRValue()) and
49+
globalValueNumber(lhs) = globalValueNumber(rhs) and
50+
valuerhs = assignExpr.getRValue() and
51+
valuelhs = assignExpr.getLValue() and // a.b.c == ((a.b).c)
52+
overlaps(valuelhs, valuerhs)
53+
select assignExpr, "An object $@ assigned to overlapping object $@.", valuelhs,
54+
valuelhs.getTarget().getName(), valuerhs, valuerhs.getTarget().getName()

c/misra/src/rules/RULE-19-1/ObjectCopiedToAnOverlappingObject.ql

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,11 @@ int getAccessByteOffset(FieldAccess fa) {
2424
result = fa.getTarget().getByteOffset() + getAccessByteOffset(fa.getQualifier())
2525
}
2626

27-
/**
28-
* Models calls to memcpy on overlapping objects
29-
*/
30-
class MemcpyCall extends Locatable {
27+
class OverlappingCopy extends Locatable {
3128
Expr src;
3229
Expr dst;
3330

34-
MemcpyCall() {
31+
OverlappingCopy() {
3532
this.(MacroInvocation).getMacroName() = "memcpy" and
3633
src = this.(MacroInvocation).getExpr().getChild(1) and
3734
dst = this.(MacroInvocation).getExpr().getChild(0)
@@ -65,14 +62,13 @@ class MemcpyCall extends Locatable {
6562
e instanceof VariableAccess and result = 0
6663
}
6764

68-
// maximum amount of element copied
6965
int getCount() {
7066
result =
7167
upperBound([this.(MacroInvocation).getExpr().getChild(2), this.(FunctionCall).getArgument(2)])
7268
}
7369

7470
// source and destination overlap
75-
predicate overlap() {
71+
predicate overlaps() {
7672
globalValueNumber(this.getBase(src)) = globalValueNumber(this.getBase(dst)) and
7773
exists(int dstStart, int dstEnd, int srcStart, int srcEnd |
7874
dstStart = this.getOffset(dst) and
@@ -96,9 +92,9 @@ class MemcpyCall extends Locatable {
9692
}
9793
}
9894

99-
from MemcpyCall memcpy
95+
from OverlappingCopy copy
10096
where
101-
not isExcluded(memcpy, Contracts7Package::objectCopiedToAnOverlappingObjectQuery()) and
102-
memcpy.overlap()
103-
select memcpy, "The object to copy $@ overlaps the object to copy $@.", memcpy.getSrc(), "from",
104-
memcpy.getDst(), "to"
97+
not isExcluded(copy, Contracts7Package::objectCopiedToAnOverlappingObjectQuery()) and
98+
copy.overlaps()
99+
select copy, "The object to copy $@ overlaps the object to copy $@.", copy.getSrc(), "from",
100+
copy.getDst(), "to"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:55:3:55:18 | ... = ... | An object $@ assigned to overlapping object $@. | test.c:55:9:55:10 | m2 | m2 | test.c:55:17:55:18 | m1 | m1 |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-19-1/ObjectAssignedToAnOverlappingObject.ql

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

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
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 |
5-
| test.c:52:3:52:8 | call to memcpy | The object to copy $@ overlaps the object to copy $@. | test.c:52:21:52:26 | & ... | from | test.c:52:10:52:18 | & ... | to |
1+
| test.c:8:3:8:8 | call to memcpy | The object to copy $@ overlaps the object to copy $@. | test.c:8:17:8:21 | & ... | from | test.c:8:10:8:14 | & ... | to |
2+
| 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 |
3+
| test.c:11:3:11:8 | call to memcpy | The object to copy $@ overlaps the object to copy $@. | test.c:11:17:11:17 | o | from | test.c:11:10:11:14 | ... + ... | to |
4+
| test.c:13:3:13:8 | call to memcpy | The object to copy $@ overlaps the object to copy $@. | test.c:13:17:13:21 | ... + ... | from | test.c:13:10:13:14 | ... + ... | to |
5+
| test.c:57:3:57:8 | call to memcpy | The object to copy $@ overlaps the object to copy $@. | test.c:57:21:57:26 | & ... | from | test.c:57:10:57:18 | & ... | to |

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
int o[10];
44
void g(void) {
5+
6+
o[2] = o[0]; // COMPLIANT
7+
58
memcpy(&o[1], &o[0], 2); // NON_COMPLIANT
69
memcpy(&o[2], &o[0], 2); // COMPLIANT
710
memcpy(&o[2], &o[1], 2); // NON_COMPLIANT
@@ -49,6 +52,8 @@ union {
4952
} u2;
5053

5154
void test_unions() {
55+
u1.m2.m2 = u1.m1; // NON_COMPLIANT
56+
5257
memcpy(&u1.m2.m2, &u1.m1, sizeof(u1.m1)); // NON_COMPLIANT
5358
memcpy(&u2.diff.suffix, &u2.fnv.suffix, sizeof(u2.fnv.suffix)); // COMPLIANT
5459
}

cpp/autosar/src/rules/M0-2-1/ObjectAssignedToAnOverlappingObject.ql

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,46 @@
1212
* external/autosar/obligation/required
1313
*/
1414

15+
//Assignment between different active members of same union instance
1516
import cpp
1617
import codingstandards.cpp.autosar
17-
import codingstandards.cpp.rules.overlappingobjectassignment.OverlappingObjectAssignment
18+
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
1819

19-
class ObjectAssignedToAnOverlappingObjectQuery extends OverlappingObjectAssignmentSharedQuery {
20-
ObjectAssignedToAnOverlappingObjectQuery() {
21-
this = RepresentationPackage::objectAssignedToAnOverlappingObjectQuery()
22-
}
20+
VariableAccess getAQualifier(VariableAccess va) { result = va.getQualifier+() }
21+
22+
int getAccessByteOffset(FieldAccess fa) {
23+
not fa.getQualifier() instanceof FieldAccess and result = fa.getTarget().getByteOffset()
24+
or
25+
result = fa.getTarget().getByteOffset() + getAccessByteOffset(fa.getQualifier())
26+
}
27+
28+
predicate overlaps(FieldAccess fa1, FieldAccess fa2) {
29+
exists(int startfa1, int endfa1, int startfa2, int endfa2 |
30+
startfa1 = getAccessByteOffset(fa1) and
31+
endfa1 = startfa1 + fa1.getTarget().getType().getSize() - 1 and
32+
startfa2 = getAccessByteOffset(fa2) and
33+
endfa2 = startfa2 + fa2.getTarget().getType().getSize() - 1
34+
|
35+
startfa1 = startfa2 and endfa1 = endfa2
36+
or
37+
startfa1 > startfa2 and endfa1 < endfa2
38+
or
39+
startfa1 < startfa2 and endfa1 < endfa2 and endfa1 > startfa2
40+
or
41+
startfa1 > startfa2 and endfa1 > endfa2 and startfa1 < endfa2
42+
)
2343
}
44+
45+
from AssignExpr assignExpr, Expr lhs, Expr rhs, ValueFieldAccess valuelhs, ValueFieldAccess valuerhs
46+
where
47+
not isExcluded(assignExpr, RepresentationPackage::objectAssignedToAnOverlappingObjectQuery()) and
48+
lhs.getType() instanceof Union and
49+
rhs.getType() instanceof Union and
50+
lhs = getAQualifier(assignExpr.getLValue()) and
51+
rhs = getAQualifier(assignExpr.getRValue()) and
52+
globalValueNumber(lhs) = globalValueNumber(rhs) and
53+
valuerhs = assignExpr.getRValue() and
54+
valuelhs = assignExpr.getLValue() and // a.b.c == ((a.b).c)
55+
overlaps(valuelhs, valuerhs)
56+
select assignExpr, "An object $@ assigned to overlapping object $@.", valuelhs,
57+
valuelhs.getTarget().getName(), valuerhs, valuerhs.getTarget().getName()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
No expected results have yet been specified
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/M0-2-1/ObjectAssignedToAnOverlappingObject.ql

rule_packages/c/Contracts7.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,12 @@
6666
},
6767
"queries": [
6868
{
69-
"description": "An object shall not be assigned to an overlapping object.",
69+
"description": "An object shall not be copied or assigned to an overlapping object.",
7070
"kind": "problem",
7171
"name": "An object shall not be assigned to an overlapping object",
7272
"precision": "high",
7373
"severity": "error",
7474
"short_name": "ObjectAssignedToAnOverlappingObject",
75-
"shared_implementation_short_name": "OverlappingObjectAssignment",
7675
"tags": [
7776
"correctness"
7877
]

rule_packages/cpp/Representation.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
"precision": "high",
5151
"severity": "error",
5252
"short_name": "ObjectAssignedToAnOverlappingObject",
53-
"shared_implementation_short_name": "OverlappingObjectAssignment",
5453
"tags": [
5554
"correctness"
5655
]

0 commit comments

Comments
 (0)