Skip to content

Commit e8006bb

Browse files
committed
C++/C#/Java: data flow AccessPath up to length 2
This commit does not include updates to test results.
1 parent aa009d0 commit e8006bb

File tree

19 files changed

+969
-228
lines changed

19 files changed

+969
-228
lines changed

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
12171217

12181218
private newtype TAccessPath =
12191219
TNil(DataFlowType t) or
1220-
TCons(Content f, int len) { len in [1 .. 5] }
1220+
TOne(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
1221+
TTwo(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
12211222

12221223
/**
12231224
* Conceptually a list of `Content`s followed by a `Type`, but only the first
@@ -1229,21 +1230,32 @@ private newtype TAccessPath =
12291230
private class AccessPath extends TAccessPath {
12301231
abstract string toString();
12311232

1232-
Content getHead() { this = TCons(result, _) }
1233+
Content getHead() {
1234+
this = TOne(result, _)
1235+
or
1236+
this = TTwo(result, _, _)
1237+
}
12331238

12341239
int len() {
12351240
this = TNil(_) and result = 0
12361241
or
1237-
this = TCons(_, result)
1242+
this = TOne(_, _) and result = 1
1243+
or
1244+
this = TTwo(_, _, result)
12381245
}
12391246

12401247
DataFlowType getType() {
12411248
this = TNil(result)
12421249
or
1243-
exists(Content head | this = TCons(head, _) | result = head.getContainerType())
1250+
result = this.getHead().getContainerType()
12441251
}
12451252

12461253
abstract AccessPathFront getFront();
1254+
1255+
/**
1256+
* Holds if `this` has `head` at the front and may be followed by `tail`.
1257+
*/
1258+
abstract predicate pop(Content head, AccessPath tail);
12471259
}
12481260

12491261
private class AccessPathNil extends AccessPath, TNil {
@@ -1252,25 +1264,50 @@ private class AccessPathNil extends AccessPath, TNil {
12521264
override AccessPathFront getFront() {
12531265
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
12541266
}
1267+
1268+
override predicate pop(Content head, AccessPath tail) { none() }
1269+
}
1270+
1271+
private class AccessPathOne extends AccessPath, TOne {
1272+
override string toString() {
1273+
exists(Content f, DataFlowType t | this = TOne(f, t) |
1274+
result = f.toString() + " : " + ppReprType(t)
1275+
)
1276+
}
1277+
1278+
override AccessPathFront getFront() {
1279+
exists(Content f | this = TOne(f, _) | result = TFrontHead(f))
1280+
}
1281+
1282+
override predicate pop(Content head, AccessPath tail) {
1283+
exists(DataFlowType t | this = TOne(head, t) and tail = TNil(t))
1284+
}
12551285
}
12561286

1257-
private class AccessPathCons extends AccessPath, TCons {
1287+
private class AccessPathTwo extends AccessPath, TTwo {
12581288
override string toString() {
1259-
exists(Content f, int len | this = TCons(f, len) |
1260-
result = f.toString() + ", ... (" + len.toString() + ")"
1289+
exists(Content f1, Content f2, int len | this = TTwo(f1, f2, len) |
1290+
result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
12611291
)
12621292
}
12631293

12641294
override AccessPathFront getFront() {
1265-
exists(Content f | this = TCons(f, _) | result = TFrontHead(f))
1295+
exists(Content f | this = TTwo(f, _, _) | result = TFrontHead(f))
1296+
}
1297+
1298+
override predicate pop(Content head, AccessPath tail) {
1299+
exists(int len, Content next | this = TTwo(head, next, len) |
1300+
tail = TTwo(next, _, len - 1)
1301+
or
1302+
len = 2 and
1303+
tail = TOne(next, _)
1304+
)
12661305
}
12671306
}
12681307

12691308
/** Holds if `ap0` corresponds to the cons of `f` and `ap`. */
12701309
private predicate pop(AccessPath ap0, Content f, AccessPath ap) {
1271-
ap0.getFront().headUsesContent(f) and
1272-
consCand(f, ap.getFront(), _) and
1273-
ap0.len() = 1 + ap.len()
1310+
ap0.pop(f, ap)
12741311
}
12751312

12761313
/** Holds if `ap0` corresponds to the cons of `f` and `ap` and `apf` is the front of `ap`. */
@@ -1814,7 +1851,9 @@ private predicate pathIntoArg(
18141851
|
18151852
ap instanceof AccessPathNil and emptyAp = true
18161853
or
1817-
ap instanceof AccessPathCons and emptyAp = false
1854+
ap instanceof AccessPathOne and emptyAp = false
1855+
or
1856+
ap instanceof AccessPathTwo and emptyAp = false
18181857
)
18191858
}
18201859

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
12171217

12181218
private newtype TAccessPath =
12191219
TNil(DataFlowType t) or
1220-
TCons(Content f, int len) { len in [1 .. 5] }
1220+
TOne(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
1221+
TTwo(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
12211222

12221223
/**
12231224
* Conceptually a list of `Content`s followed by a `Type`, but only the first
@@ -1229,21 +1230,32 @@ private newtype TAccessPath =
12291230
private class AccessPath extends TAccessPath {
12301231
abstract string toString();
12311232

1232-
Content getHead() { this = TCons(result, _) }
1233+
Content getHead() {
1234+
this = TOne(result, _)
1235+
or
1236+
this = TTwo(result, _, _)
1237+
}
12331238

12341239
int len() {
12351240
this = TNil(_) and result = 0
12361241
or
1237-
this = TCons(_, result)
1242+
this = TOne(_, _) and result = 1
1243+
or
1244+
this = TTwo(_, _, result)
12381245
}
12391246

12401247
DataFlowType getType() {
12411248
this = TNil(result)
12421249
or
1243-
exists(Content head | this = TCons(head, _) | result = head.getContainerType())
1250+
result = this.getHead().getContainerType()
12441251
}
12451252

12461253
abstract AccessPathFront getFront();
1254+
1255+
/**
1256+
* Holds if `this` has `head` at the front and may be followed by `tail`.
1257+
*/
1258+
abstract predicate pop(Content head, AccessPath tail);
12471259
}
12481260

12491261
private class AccessPathNil extends AccessPath, TNil {
@@ -1252,25 +1264,50 @@ private class AccessPathNil extends AccessPath, TNil {
12521264
override AccessPathFront getFront() {
12531265
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
12541266
}
1267+
1268+
override predicate pop(Content head, AccessPath tail) { none() }
1269+
}
1270+
1271+
private class AccessPathOne extends AccessPath, TOne {
1272+
override string toString() {
1273+
exists(Content f, DataFlowType t | this = TOne(f, t) |
1274+
result = f.toString() + " : " + ppReprType(t)
1275+
)
1276+
}
1277+
1278+
override AccessPathFront getFront() {
1279+
exists(Content f | this = TOne(f, _) | result = TFrontHead(f))
1280+
}
1281+
1282+
override predicate pop(Content head, AccessPath tail) {
1283+
exists(DataFlowType t | this = TOne(head, t) and tail = TNil(t))
1284+
}
12551285
}
12561286

1257-
private class AccessPathCons extends AccessPath, TCons {
1287+
private class AccessPathTwo extends AccessPath, TTwo {
12581288
override string toString() {
1259-
exists(Content f, int len | this = TCons(f, len) |
1260-
result = f.toString() + ", ... (" + len.toString() + ")"
1289+
exists(Content f1, Content f2, int len | this = TTwo(f1, f2, len) |
1290+
result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
12611291
)
12621292
}
12631293

12641294
override AccessPathFront getFront() {
1265-
exists(Content f | this = TCons(f, _) | result = TFrontHead(f))
1295+
exists(Content f | this = TTwo(f, _, _) | result = TFrontHead(f))
1296+
}
1297+
1298+
override predicate pop(Content head, AccessPath tail) {
1299+
exists(int len, Content next | this = TTwo(head, next, len) |
1300+
tail = TTwo(next, _, len - 1)
1301+
or
1302+
len = 2 and
1303+
tail = TOne(next, _)
1304+
)
12661305
}
12671306
}
12681307

12691308
/** Holds if `ap0` corresponds to the cons of `f` and `ap`. */
12701309
private predicate pop(AccessPath ap0, Content f, AccessPath ap) {
1271-
ap0.getFront().headUsesContent(f) and
1272-
consCand(f, ap.getFront(), _) and
1273-
ap0.len() = 1 + ap.len()
1310+
ap0.pop(f, ap)
12741311
}
12751312

12761313
/** Holds if `ap0` corresponds to the cons of `f` and `ap` and `apf` is the front of `ap`. */
@@ -1814,7 +1851,9 @@ private predicate pathIntoArg(
18141851
|
18151852
ap instanceof AccessPathNil and emptyAp = true
18161853
or
1817-
ap instanceof AccessPathCons and emptyAp = false
1854+
ap instanceof AccessPathOne and emptyAp = false
1855+
or
1856+
ap instanceof AccessPathTwo and emptyAp = false
18181857
)
18191858
}
18201859

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,8 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
12171217

12181218
private newtype TAccessPath =
12191219
TNil(DataFlowType t) or
1220-
TCons(Content f, int len) { len in [1 .. 5] }
1220+
TOne(Content f, DataFlowType t) { consCand(f, TFrontNil(t), _) } or
1221+
TTwo(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
12211222

12221223
/**
12231224
* Conceptually a list of `Content`s followed by a `Type`, but only the first
@@ -1229,21 +1230,32 @@ private newtype TAccessPath =
12291230
private class AccessPath extends TAccessPath {
12301231
abstract string toString();
12311232

1232-
Content getHead() { this = TCons(result, _) }
1233+
Content getHead() {
1234+
this = TOne(result, _)
1235+
or
1236+
this = TTwo(result, _, _)
1237+
}
12331238

12341239
int len() {
12351240
this = TNil(_) and result = 0
12361241
or
1237-
this = TCons(_, result)
1242+
this = TOne(_, _) and result = 1
1243+
or
1244+
this = TTwo(_, _, result)
12381245
}
12391246

12401247
DataFlowType getType() {
12411248
this = TNil(result)
12421249
or
1243-
exists(Content head | this = TCons(head, _) | result = head.getContainerType())
1250+
result = this.getHead().getContainerType()
12441251
}
12451252

12461253
abstract AccessPathFront getFront();
1254+
1255+
/**
1256+
* Holds if `this` has `head` at the front and may be followed by `tail`.
1257+
*/
1258+
abstract predicate pop(Content head, AccessPath tail);
12471259
}
12481260

12491261
private class AccessPathNil extends AccessPath, TNil {
@@ -1252,25 +1264,50 @@ private class AccessPathNil extends AccessPath, TNil {
12521264
override AccessPathFront getFront() {
12531265
exists(DataFlowType t | this = TNil(t) | result = TFrontNil(t))
12541266
}
1267+
1268+
override predicate pop(Content head, AccessPath tail) { none() }
1269+
}
1270+
1271+
private class AccessPathOne extends AccessPath, TOne {
1272+
override string toString() {
1273+
exists(Content f, DataFlowType t | this = TOne(f, t) |
1274+
result = f.toString() + " : " + ppReprType(t)
1275+
)
1276+
}
1277+
1278+
override AccessPathFront getFront() {
1279+
exists(Content f | this = TOne(f, _) | result = TFrontHead(f))
1280+
}
1281+
1282+
override predicate pop(Content head, AccessPath tail) {
1283+
exists(DataFlowType t | this = TOne(head, t) and tail = TNil(t))
1284+
}
12551285
}
12561286

1257-
private class AccessPathCons extends AccessPath, TCons {
1287+
private class AccessPathTwo extends AccessPath, TTwo {
12581288
override string toString() {
1259-
exists(Content f, int len | this = TCons(f, len) |
1260-
result = f.toString() + ", ... (" + len.toString() + ")"
1289+
exists(Content f1, Content f2, int len | this = TTwo(f1, f2, len) |
1290+
result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
12611291
)
12621292
}
12631293

12641294
override AccessPathFront getFront() {
1265-
exists(Content f | this = TCons(f, _) | result = TFrontHead(f))
1295+
exists(Content f | this = TTwo(f, _, _) | result = TFrontHead(f))
1296+
}
1297+
1298+
override predicate pop(Content head, AccessPath tail) {
1299+
exists(int len, Content next | this = TTwo(head, next, len) |
1300+
tail = TTwo(next, _, len - 1)
1301+
or
1302+
len = 2 and
1303+
tail = TOne(next, _)
1304+
)
12661305
}
12671306
}
12681307

12691308
/** Holds if `ap0` corresponds to the cons of `f` and `ap`. */
12701309
private predicate pop(AccessPath ap0, Content f, AccessPath ap) {
1271-
ap0.getFront().headUsesContent(f) and
1272-
consCand(f, ap.getFront(), _) and
1273-
ap0.len() = 1 + ap.len()
1310+
ap0.pop(f, ap)
12741311
}
12751312

12761313
/** Holds if `ap0` corresponds to the cons of `f` and `ap` and `apf` is the front of `ap`. */
@@ -1814,7 +1851,9 @@ private predicate pathIntoArg(
18141851
|
18151852
ap instanceof AccessPathNil and emptyAp = true
18161853
or
1817-
ap instanceof AccessPathCons and emptyAp = false
1854+
ap instanceof AccessPathOne and emptyAp = false
1855+
or
1856+
ap instanceof AccessPathTwo and emptyAp = false
18181857
)
18191858
}
18201859

0 commit comments

Comments
 (0)