Skip to content

Commit 5edc533

Browse files
authored
Merge pull request #551 from kraiouchkine/a8-4-7-fix-429
A8-4-7: Consider non-trivially-copyable types
2 parents bc53286 + 160ac0c commit 5edc533

8 files changed

+57
-14
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- `A8-4-7` - `InParametersForNotCheapToCopyTypesNotPassedByReference.ql`, `InParametersForCheapToCopyTypesNotPassedByValue.ql`:
2+
- Improve coverage of the query by additionally alerting to non-trivially-copyable types being passed by value.
3+
- Non-trivially-copyable types not passed by value will no longer be incorrectly reported.

cpp/autosar/src/rules/A8-4-7/InParametersForCheapToCopyTypesNotPassedByValue.ql

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import cpp
1717
import codingstandards.cpp.autosar
18-
import TriviallySmallType
18+
import TriviallyCopyableSmallType
1919
import codingstandards.cpp.CommonTypes as CommonTypes
2020
import codingstandards.cpp.Class
2121

@@ -26,7 +26,7 @@ import codingstandards.cpp.Class
2626
* In this rule, we will look cases where a "cheap to copy" type is not passed by value.
2727
*/
2828

29-
from Parameter v, TriviallySmallType t
29+
from Parameter v, TriviallyCopyableSmallType t
3030
where
3131
not isExcluded(v, ClassesPackage::inParametersForCheapToCopyTypesNotPassedByValueQuery()) and
3232
exists(ReferenceType rt |
@@ -40,5 +40,6 @@ where
4040
not v.isFromUninstantiatedTemplate(_) and
4141
not v.isFromTemplateInstantiation(_)
4242
select v,
43-
"Parameter '" + v.getName() + "' is the trivially copyable type '" + t.getName() +
44-
"' but it is passed by reference instead of by value."
43+
"Parameter '" + v.getName() +
44+
"' is the trivially copyable type $@ but it is passed by reference instead of by value.", t,
45+
t.getName()

cpp/autosar/src/rules/A8-4-7/InParametersForNotCheapToCopyTypesNotPassedByReference.ql

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import cpp
1717
import codingstandards.cpp.autosar
18-
import TriviallySmallType
18+
import TriviallyCopyableSmallType
1919
import codingstandards.cpp.CommonTypes as CommonTypes
2020

2121
/*
@@ -28,12 +28,12 @@ import codingstandards.cpp.CommonTypes as CommonTypes
2828
from Parameter v
2929
where
3030
not isExcluded(v, ClassesPackage::inParametersForNotCheapToCopyTypesNotPassedByReferenceQuery()) and
31-
not v.getType() instanceof TriviallySmallType and
31+
not v.getType() instanceof TriviallyCopyableSmallType and
3232
not v.getType().getUnderlyingType() instanceof ReferenceType and
3333
not exists(CatchBlock cb | cb.getParameter() = v) and
3434
not v.isFromUninstantiatedTemplate(_) and
3535
not v.isFromTemplateInstantiation(_)
3636
select v,
37-
"Parameter " + v.getName() +
38-
" is the trivially non-copyable type $@ but it is passed by value instead of by reference.",
37+
"Parameter '" + v.getName() +
38+
"' is the trivially non-copyable type $@ but it is passed by value instead of by reference.",
3939
v.getType(), v.getType().getName()

cpp/autosar/src/rules/A8-4-7/TriviallySmallType.qll renamed to cpp/autosar/src/rules/A8-4-7/TriviallyCopyableSmallType.qll

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import cpp
22
import codingstandards.cpp.autosar
3+
import codingstandards.cpp.TrivialType
34

45
/**
56
* Get the largest word size, in bytes. Some projects may have multiple different
@@ -13,6 +14,9 @@ int wordSize() { result = max(VoidPointerType v | | v.getSize()) }
1314
bindingset[bytes]
1415
int bytesToWords(int bytes) { result = bytes / wordSize() }
1516

16-
class TriviallySmallType extends Type {
17-
TriviallySmallType() { exists(int size | size = this.getSize() | bytesToWords(size) <= 2) }
17+
class TriviallyCopyableSmallType extends Type {
18+
TriviallyCopyableSmallType() {
19+
isTriviallyCopyableType(this) and
20+
exists(int size | size = this.getSize() | bytesToWords(size) <= 2)
21+
}
1822
}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| test.cpp:20:19:20:21 | f5a | Parameter 'f5a' is the trivially copyable type 'const S1' but it is passed by reference instead of by value. |
1+
| test.cpp:22:19:22:21 | f5a | Parameter 'f5a' is the trivially copyable type $@ but it is passed by reference instead of by value. | file://:0:0:0:0 | const S1 | const S1 |
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
| test.cpp:23:12:23:14 | f8a | Parameter f8a is the trivially non-copyable type $@ but it is passed by value instead of by reference. | test.cpp:14:8:14:9 | S2 | S2 |
2-
| test.cpp:27:13:27:16 | f12a | Parameter f12a is the trivially non-copyable type $@ but it is passed by value instead of by reference. | test.cpp:14:8:14:9 | S2 | S2 |
1+
| test.cpp:25:12:25:14 | f8a | Parameter 'f8a' is the trivially non-copyable type $@ but it is passed by value instead of by reference. | test.cpp:16:8:16:9 | S2 | S2 |
2+
| test.cpp:29:13:29:16 | f12a | Parameter 'f12a' is the trivially non-copyable type $@ but it is passed by value instead of by reference. | test.cpp:16:8:16:9 | S2 | S2 |
3+
| test.cpp:70:13:70:16 | f17a | Parameter 'f17a' is the trivially non-copyable type $@ but it is passed by value instead of by reference. | test.cpp:60:8:60:9 | S4 | S4 |

cpp/autosar/test/rules/A8-4-7/test.cpp

+24-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
#include <array>
12
#include <cstdint>
23
#include <string>
4+
#include <vector>
35

46
void f1(std::uint8_t f1a) {} // COMPLIANT
57
void f2(std::uint16_t f2a) {} // COMPLIANT
@@ -45,4 +47,25 @@ class C1 {};
4547
class C2 : public C1 {
4648
public:
4749
C2 &operator=(const C2 &); // COMPLIANT
48-
};
50+
};
51+
52+
void f13(double f13a) {} // COMPLIANT
53+
void f14(const double f14a) {} // COMPLIANT
54+
55+
struct S3 {
56+
int x;
57+
S3() : x(0) {} // COMPLIANT
58+
};
59+
60+
struct S4 {
61+
~S4() {} // non-trivial destructor
62+
};
63+
64+
struct S5 {
65+
const int y;
66+
S5(int value) : y(value) {}
67+
};
68+
69+
void f15(S3 f15a) {} // COMPLIANT
70+
void f17(S4 f17a) {} // NON_COMPLIANT (S4 has a non-trivial destructor)
71+
void f18(S5 f18a) {} // COMPLIANT

cpp/common/src/codingstandards/cpp/TrivialType.qll

+11
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,17 @@ predicate isTrivialType(Type t) {
281281
isTrivialType(t.getUnspecifiedType())
282282
}
283283

284+
/** Holds if `t` is a trivially copyable type. */
285+
predicate isTriviallyCopyableType(Type t) {
286+
isScalarType(t)
287+
or
288+
t instanceof TriviallyCopyableClass
289+
or
290+
isTriviallyCopyableType(t.(ArrayType).getBaseType())
291+
or
292+
isTriviallyCopyableType(t.getUnspecifiedType())
293+
}
294+
284295
/** A POD type as defined by [basic.types]/9. */
285296
class PODType extends Type {
286297
PODType() {

0 commit comments

Comments
 (0)