Skip to content

Commit 32b6e9b

Browse files
committed
CPP: Exclude cases where the parameter is written to.
1 parent 54c766c commit 32b6e9b

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

cpp/ql/src/Critical/LargeParameter.ql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* non-attributable
1212
*/
1313
import cpp
14+
import semmle.code.cpp.dataflow.EscapesTree
1415

1516
from Function f, Parameter p, Type t, int size
1617
where f.getAParameter() = p
@@ -19,6 +20,16 @@ where f.getAParameter() = p
1920
and size > 64
2021
and not t.getUnderlyingType() instanceof ArrayType
2122
and not f instanceof CopyAssignmentOperator
23+
// exception: p is written to, which may mean the copy is intended
24+
and not p.getAnAccess().isAddressOfAccessNonConst()
25+
and not exists(Access a |
26+
a.getTarget() = p and
27+
(
28+
exists(Assignment an | an.getLValue().getAChild*() = a) or
29+
exists(CrementOperation co | co.getOperand().getAChild*() = a) or
30+
exists(FunctionCall fc | fc.getQualifier().getAChild*() = a and not fc.getTarget().hasSpecifier("const"))
31+
)
32+
)
2233
select
2334
p, "This parameter of type $@ is " + size.toString() + " bytes - consider passing a const pointer/reference instead.",
2435
t, t.toString()
Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
| test.cpp:16:13:16:14 | _t | This parameter of type $@ is 4096 bytes - consider passing a const pointer/reference instead. | test.cpp:6:8:6:20 | myLargeStruct | myLargeStruct |
22
| test.cpp:24:44:24:48 | mtc_t | This parameter of type $@ is 4096 bytes - consider passing a const pointer/reference instead. | test.cpp:11:7:11:21 | myTemplateClass<myLargeStruct> | myTemplateClass<myLargeStruct> |
33
| test.cpp:28:49:28:49 | b | This parameter of type $@ is 4096 bytes - consider passing a const pointer/reference instead. | test.cpp:6:8:6:20 | myLargeStruct | myLargeStruct |
4-
| test.cpp:78:16:78:16 | a | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
5-
| test.cpp:79:16:79:16 | b | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
6-
| test.cpp:80:16:80:16 | c | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
7-
| test.cpp:81:16:81:16 | d | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
8-
| test.cpp:82:16:82:16 | e | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
9-
| test.cpp:83:16:83:16 | f | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
10-
| test.cpp:84:16:84:16 | g | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
114
| test.cpp:104:16:104:16 | a | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
125
| test.cpp:105:16:105:16 | b | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
136
| test.cpp:106:16:106:16 | c | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
147
| test.cpp:107:16:107:16 | d | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
158
| test.cpp:108:16:108:16 | e | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
169
| test.cpp:109:16:109:16 | f | This parameter of type $@ is 4100 bytes - consider passing a const pointer/reference instead. | test.cpp:58:8:58:19 | MyLargeClass | MyLargeClass |
17-
| test.cpp:144:47:144:49 | lhs | This parameter of type $@ is 1028 bytes - consider passing a const pointer/reference instead. | test.cpp:130:7:130:23 | MyArithmeticClass | MyArithmeticClass |

cpp/ql/test/query-tests/Critical/LargeParameter/test.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@ int mlc_get(const MyLargeClass &c) {
7575
}
7676

7777
void myFunction4(
78-
MyLargeClass a, // GOOD: large, but the copy is written to so can't be trivially replaced with a reference [FALSE POSITIVE]
79-
MyLargeClass b, // GOOD [FALSE POSITIVE]
80-
MyLargeClass c, // GOOD [FALSE POSITIVE]
81-
MyLargeClass d, // GOOD [FALSE POSITIVE]
82-
MyLargeClass e, // GOOD [FALSE POSITIVE]
83-
MyLargeClass f, // GOOD [FALSE POSITIVE]
84-
MyLargeClass g // GOOD [FALSE POSITIVE]
78+
MyLargeClass a, // GOOD: large, but the copy is written to so can't be trivially replaced with a reference
79+
MyLargeClass b, // GOOD
80+
MyLargeClass c, // GOOD
81+
MyLargeClass d, // GOOD
82+
MyLargeClass e, // GOOD
83+
MyLargeClass f, // GOOD
84+
MyLargeClass g // GOOD
8585
)
8686
{
8787
MyLargeClass *mlc_ptr;
@@ -141,7 +141,7 @@ class MyArithmeticClass {
141141
char data[1024];
142142
};
143143

144-
MyArithmeticClass operator+(MyArithmeticClass lhs, const MyArithmeticClass &rhs) { // GOOD [FALSE POSITIVE]
144+
MyArithmeticClass operator+(MyArithmeticClass lhs, const MyArithmeticClass &rhs) { // GOOD
145145
lhs += rhs; // lhs is copied by design
146146
return lhs;
147147
}

0 commit comments

Comments
 (0)