Skip to content

Commit 41d5d5a

Browse files
authored
Merge pull request #1438 from geoffw0/assignedvalue
CPP: Support for aggregate initializers in getAnAssignedValue()
2 parents b9703b7 + 37a1c48 commit 41d5d5a

File tree

7 files changed

+94
-1
lines changed

7 files changed

+94
-1
lines changed

change-notes/1.22/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515

1616
## Changes to QL libraries
1717

18+
- The predicate `Variable.getAnAssignedValue()` now reports assignments to fields resulting from aggregate initialization (` = {...}`).
1819
- The predicate `TypeMention.toString()` has been simplified to always return the string "`type mention`". This may improve performance when using `Element.toString()` or its descendants.

cpp/ql/src/jsf/4.10 Classes/AV Rule 71.ql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ predicate memberDirectlyInitialisesVariable(MemberFunction mf, Class c, MemberVa
5555
predicate memberInitialisesVariable(MemberFunction mf, Class c, MemberVariable mv) {
5656
memberDirectlyInitialisesVariable(mf, c, mv) or
5757
exists(MemberFunction mf2 |
58+
memberDirectlyInitialisesVariable(_, c, mv) and // (optimizer hint)
5859
memberInitialisesVariable(mf2, c, mv) and
5960
mf.getDeclaringType() = c and
6061
mf.calls(mf2)

cpp/ql/src/semmle/code/cpp/Field.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class Field extends MemberVariable {
5454
* which the field will be initialized, whether by an initializer list or in a
5555
* constructor.
5656
*/
57-
final int getInitializationOrder() {
57+
final pragma[nomagic] int getInitializationOrder() {
5858
exists(Class cls, int memberIndex |
5959
this = cls.getCanonicalMember(memberIndex) and
6060
memberIndex = rank[result + 1](int index |

cpp/ql/src/semmle/code/cpp/Variable.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ class Variable extends Declaration, @variable {
117117
or
118118
exists (AssignExpr ae
119119
| ae.getLValue().(Access).getTarget() = this and result = ae.getRValue())
120+
or
121+
exists(AggregateLiteral l |
122+
this.getDeclaringType() = l.getType() and
123+
result = l.getChild(this.(Field).getInitializationOrder())
124+
)
120125
}
121126

122127
/**
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
| file://:0:0:0:0 | abc | test.cpp:53:6:53:11 | chars1 |
2+
| file://:0:0:0:0 | {...} | test.cpp:38:22:38:22 | v |
3+
| test.cpp:4:9:4:11 | 10 | test.cpp:4:6:4:6 | v |
4+
| test.cpp:5:15:5:16 | & ... | test.cpp:5:7:5:11 | ptr_v |
5+
| test.cpp:6:15:6:15 | v | test.cpp:6:7:6:11 | ref_v |
6+
| test.cpp:8:6:8:7 | 11 | test.cpp:4:6:4:6 | v |
7+
| test.cpp:10:10:10:11 | 13 | test.cpp:6:7:6:11 | ref_v |
8+
| test.cpp:11:6:11:10 | ... + ... | test.cpp:4:6:4:6 | v |
9+
| test.cpp:19:32:19:35 | 0.0 | test.cpp:19:27:19:28 | _y |
10+
| test.cpp:19:42:19:43 | _x | test.cpp:24:8:24:8 | x |
11+
| test.cpp:19:49:19:50 | _y | test.cpp:24:11:24:11 | y |
12+
| test.cpp:19:54:19:60 | 0.0 | test.cpp:24:14:24:14 | z |
13+
| test.cpp:35:16:35:25 | {...} | test.cpp:35:11:35:12 | v1 |
14+
| test.cpp:35:17:35:17 | 1 | test.cpp:31:6:31:8 | num |
15+
| test.cpp:35:20:35:24 | One | test.cpp:32:14:32:16 | str |
16+
| test.cpp:36:16:36:39 | {...} | test.cpp:36:11:36:12 | v2 |
17+
| test.cpp:36:24:36:24 | 2 | test.cpp:31:6:31:8 | num |
18+
| test.cpp:36:34:36:38 | Two | test.cpp:32:14:32:16 | str |
19+
| test.cpp:38:27:38:27 | 3 | test.cpp:31:6:31:8 | num |
20+
| test.cpp:38:30:38:36 | Three | test.cpp:32:14:32:16 | str |
21+
| test.cpp:48:16:48:28 | {...} | test.cpp:48:11:48:12 | v3 |
22+
| test.cpp:48:17:48:27 | {...} | test.cpp:45:12:45:14 | ms2 |
23+
| test.cpp:48:18:48:18 | 4 | test.cpp:31:6:31:8 | num |
24+
| test.cpp:48:21:48:26 | Four | test.cpp:32:14:32:16 | str |
25+
| test.cpp:52:19:52:27 | {...} | test.cpp:52:5:52:11 | myArray |
26+
| test.cpp:54:17:54:31 | {...} | test.cpp:54:6:54:11 | chars2 |
27+
| test.cpp:55:16:55:20 | abc | test.cpp:55:7:55:12 | chars3 |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import cpp
2+
3+
from Variable v
4+
select v.getAnAssignedValue(), v
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
void test1()
3+
{
4+
int v = 10; // assignment to `v`
5+
int *ptr_v = &v; // assignment to `ptr_v`
6+
int &ref_v = v; // assignment to `ref_v`
7+
8+
v = 11; // assignment to `v`
9+
*ptr_v = 12;
10+
ref_v = 13; // assignment to `ref_v`
11+
v = v + 1; // assignment to `v`
12+
v += 1;
13+
v++;
14+
}
15+
16+
class myClass1
17+
{
18+
public:
19+
myClass1(float _x, float _y = 0.0f) : x(_x), y(_y), z(0.0f) { // assignments to `_y`, `x`, `y`, `z`
20+
// ...
21+
}
22+
23+
private:
24+
float x, y, z;
25+
};
26+
27+
// ---
28+
29+
struct myStruct1
30+
{
31+
int num;
32+
const char *str;
33+
};
34+
35+
myStruct1 v1 = {1, "One"}; // assigments to `v1`, `num`, `str`
36+
myStruct1 v2 = {.num = 2, .str = "Two"}; // assigments to `v2`, `num`, `str`
37+
38+
void test2(myStruct1 v = {3, "Three"}) // assignments to `v` (literal `{...}` has no location), `num`, `str`
39+
{
40+
// ...
41+
}
42+
43+
struct myStruct2
44+
{
45+
myStruct1 ms2;
46+
};
47+
48+
myStruct2 v3 = {{4, "Four"}}; // assigments to `v3`, `ms2`, `num`, `str`
49+
50+
// ---
51+
52+
int myArray[10] = {1, 2, 3}; // assigment to `myArray`
53+
char chars1[] = "abc"; // assignment to `chars1` (literal "abc" has no location)
54+
char chars2[] = {'a', 'b', 'c'}; // assigment to `chars2`
55+
char *chars3 = "abc"; // assigment to `chars3`

0 commit comments

Comments
 (0)