Skip to content

Commit bf58b6c

Browse files
committed
Java: Remove self-ref tracking; improve AccessPath.toString on numbers.
1 parent 3af91d5 commit bf58b6c

File tree

4 files changed

+37
-98
lines changed

4 files changed

+37
-98
lines changed

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

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,9 @@ class Content extends TContent {
6969
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
7070
}
7171
/** Gets the type of the object containing this content. */
72-
abstract RefType getDeclaringType();
72+
abstract RefType getContainerType();
7373
/** Gets the type of this content. */
7474
abstract Type getType();
75-
/**
76-
* Holds if this content may contain an object of the same type as the one
77-
* that contains this content, and if this fact should be used to compress
78-
* access paths.
79-
*
80-
* Examples include the tail pointer in a linked list or the left and right
81-
* pointers in a binary tree.
82-
*/
83-
predicate isSelfRef() { none() }
8475
}
8576
private class FieldContent extends Content, TFieldContent {
8677
Field f;
@@ -90,17 +81,17 @@ private class FieldContent extends Content, TFieldContent {
9081
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
9182
f.getLocation().hasLocationInfo(path, sl, sc, el, ec)
9283
}
93-
override RefType getDeclaringType() { result = f.getDeclaringType() }
84+
override RefType getContainerType() { result = f.getDeclaringType() }
9485
override Type getType() { result = f.getType() }
9586
}
9687
private class CollectionContent extends Content, TCollectionContent {
9788
override string toString() { result = "collection" }
98-
override RefType getDeclaringType() { none() }
89+
override RefType getContainerType() { none() }
9990
override Type getType() { none() }
10091
}
10192
private class ArrayContent extends Content, TArrayContent {
10293
override string toString() { result = "array" }
103-
override RefType getDeclaringType() { none() }
94+
override RefType getContainerType() { none() }
10495
override Type getType() { none() }
10596
}
10697

@@ -132,6 +123,11 @@ RefType getErasedRepr(Type t) {
132123
result instanceof VoidType // stub implementation
133124
}
134125

126+
/** Gets a string representation of a type returned by `getErasedRepr`. */
127+
string ppReprType(Type t) {
128+
result = t.toString()
129+
}
130+
135131
/**
136132
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
137133
* a node of type `t1` to a node of type `t2`.

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

Lines changed: 11 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -724,76 +724,27 @@ private predicate localFlowBigStep(
724724
localFlowExit(node2, config)
725725
}
726726

727-
/**
728-
* Holds if `f` may contain an object of the same type, `t`, as the one
729-
* that contains `f`, and if this fact should be used to compress
730-
* access paths.
731-
*
732-
* Examples include the tail pointer in a linked list or the left and right
733-
* pointers in a binary tree.
734-
*/
735-
private predicate selfRef(Content f, RefType t) {
736-
t = f.getDeclaringType() and
737-
f.isSelfRef()
738-
}
739-
740-
private newtype TFlowContainer =
741-
TRegularContent(Content f) { not selfRef(f, _) } or
742-
TSelfRefContent(RefType t) { selfRef(_, t) }
743-
744-
/**
745-
* A `Content` or a `Content` abstracted as its declaring type.
746-
*
747-
* Sequences of one or more `Content`s in the same declaring type for which
748-
* `isSelfRef()` holds are represented as a single `FlowContainer` in an
749-
* `AccessPath`.
750-
*/
751-
private class FlowContainer extends TFlowContainer {
752-
string toString() {
753-
exists(Content f | this = TRegularContent(f) and result = f.toString())
754-
or
755-
exists(RefType t | this = TSelfRefContent(t) and result = t.toString())
756-
}
757-
758-
predicate usesContent(Content f) {
759-
this = TRegularContent(f)
760-
or
761-
exists(RefType t | this = TSelfRefContent(t) and selfRef(f, t))
762-
}
763-
764-
RefType getContainerType() {
765-
exists(Content f | this = TRegularContent(f) and result = f.getDeclaringType())
766-
or
767-
this = TSelfRefContent(result)
768-
}
769-
}
770-
771727
private newtype TAccessPathFront =
772728
TFrontNil(Type t) or
773-
TFrontHead(FlowContainer f)
729+
TFrontHead(Content f)
774730

775731
/**
776732
* The front of an `AccessPath`. This is either a head or a nil.
777733
*/
778734
private class AccessPathFront extends TAccessPathFront {
779735
string toString() {
780-
exists(Type t | this = TFrontNil(t) | result = t.toString())
736+
exists(Type t | this = TFrontNil(t) | result = ppReprType(t))
781737
or
782-
exists(FlowContainer f | this = TFrontHead(f) | result = f.toString())
738+
exists(Content f | this = TFrontHead(f) | result = f.toString())
783739
}
784740

785741
Type getType() {
786742
this = TFrontNil(result)
787743
or
788-
exists(FlowContainer head | this = TFrontHead(head) | result = head.getContainerType())
744+
exists(Content head | this = TFrontHead(head) | result = head.getContainerType())
789745
}
790746

791-
predicate headUsesContent(Content f) {
792-
exists(FlowContainer fc |
793-
fc.usesContent(f) and
794-
this = TFrontHead(fc)
795-
)
796-
}
747+
predicate headUsesContent(Content f) { this = TFrontHead(f) }
797748
}
798749

799750
private class AccessPathFrontNil extends AccessPathFront, TFrontNil { }
@@ -1004,7 +955,7 @@ private predicate consCand(Content f, AccessPathFront apf, Configuration config)
1004955

1005956
private newtype TAccessPath =
1006957
TNil(Type t) or
1007-
TCons(FlowContainer f, int len) { len in [1 .. 5] }
958+
TCons(Content f, int len) { len in [1 .. 5] }
1008959

1009960
/**
1010961
* Conceptually a list of `Content`s followed by a `Type`, but only the first
@@ -1016,7 +967,7 @@ private newtype TAccessPath =
1016967
private class AccessPath extends TAccessPath {
1017968
abstract string toString();
1018969

1019-
FlowContainer getHead() { this = TCons(result, _) }
970+
Content getHead() { this = TCons(result, _) }
1020971

1021972
int len() {
1022973
this = TNil(_) and result = 0
@@ -1027,27 +978,27 @@ private class AccessPath extends TAccessPath {
1027978
Type getType() {
1028979
this = TNil(result)
1029980
or
1030-
exists(FlowContainer head | this = TCons(head, _) | result = head.getContainerType())
981+
exists(Content head | this = TCons(head, _) | result = head.getContainerType())
1031982
}
1032983

1033984
abstract AccessPathFront getFront();
1034985
}
1035986

1036987
private class AccessPathNil extends AccessPath, TNil {
1037-
override string toString() { exists(Type t | this = TNil(t) | result = t.toString()) }
988+
override string toString() { exists(Type t | this = TNil(t) | result = ppReprType(t)) }
1038989

1039990
override AccessPathFront getFront() { exists(Type t | this = TNil(t) | result = TFrontNil(t)) }
1040991
}
1041992

1042993
private class AccessPathCons extends AccessPath, TCons {
1043994
override string toString() {
1044-
exists(FlowContainer f, int len | this = TCons(f, len) |
995+
exists(Content f, int len | this = TCons(f, len) |
1045996
result = f.toString() + ", ... (" + len.toString() + ")"
1046997
)
1047998
}
1048999

10491000
override AccessPathFront getFront() {
1050-
exists(FlowContainer f | this = TCons(f, _) | result = TFrontHead(f))
1001+
exists(Content f | this = TCons(f, _) | result = TFrontHead(f))
10511002
}
10521003
}
10531004

java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ private module ImplCommon {
118118
node1.(ArgumentNode).argumentOf(call, i1) and
119119
node2.getPreUpdateNode().(ArgumentNode).argumentOf(call, i2) and
120120
compatibleTypes(node1.getTypeBound(), f.getType()) and
121-
compatibleTypes(node2.getTypeBound(), f.getDeclaringType())
121+
compatibleTypes(node2.getTypeBound(), f.getContainerType())
122122
)
123123
}
124124

@@ -149,7 +149,7 @@ private module ImplCommon {
149149
setterReturn(p, f) and
150150
arg.argumentOf(node2.asExpr(), _) and
151151
compatibleTypes(node1.getTypeBound(), f.getType()) and
152-
compatibleTypes(node2.getTypeBound(), f.getDeclaringType())
152+
compatibleTypes(node2.getTypeBound(), f.getContainerType())
153153
)
154154
}
155155

@@ -174,7 +174,7 @@ private module ImplCommon {
174174
viableParamArg(p, arg) and
175175
getter(p, f) and
176176
arg.argumentOf(node2.asExpr(), _) and
177-
compatibleTypes(node1.getTypeBound(), f.getDeclaringType()) and
177+
compatibleTypes(node1.getTypeBound(), f.getContainerType()) and
178178
compatibleTypes(node2.getTypeBound(), f.getType())
179179
)
180180
}

java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -118,20 +118,10 @@ class Content extends TContent {
118118
}
119119

120120
/** Gets the type of the object containing this content. */
121-
abstract RefType getDeclaringType();
121+
abstract RefType getContainerType();
122122

123123
/** Gets the type of this content. */
124124
abstract Type getType();
125-
126-
/**
127-
* Holds if this content may contain an object of the same type as the one
128-
* that contains this content, and if this fact should be used to compress
129-
* access paths.
130-
*
131-
* Examples include the tail pointer in a linked list or the left and right
132-
* pointers in a binary tree.
133-
*/
134-
predicate isSelfRef() { none() }
135125
}
136126

137127
private class FieldContent extends Content, TFieldContent {
@@ -147,25 +137,23 @@ private class FieldContent extends Content, TFieldContent {
147137
f.getLocation().hasLocationInfo(path, sl, sc, el, ec)
148138
}
149139

150-
override RefType getDeclaringType() { result = f.getDeclaringType() }
140+
override RefType getContainerType() { result = f.getDeclaringType() }
151141

152142
override Type getType() { result = getFieldTypeBound(f) }
153-
154-
override predicate isSelfRef() { compatibleTypes(getDeclaringType(), getType()) }
155143
}
156144

157145
private class CollectionContent extends Content, TCollectionContent {
158146
override string toString() { result = "collection" }
159147

160-
override RefType getDeclaringType() { none() }
148+
override RefType getContainerType() { none() }
161149

162150
override Type getType() { none() }
163151
}
164152

165153
private class ArrayContent extends Content, TArrayContent {
166154
override string toString() { result = "array" }
167155

168-
override RefType getDeclaringType() { none() }
156+
override RefType getContainerType() { none() }
169157

170158
override Type getType() { none() }
171159
}
@@ -212,6 +200,13 @@ RefType getErasedRepr(Type t) {
212200
)
213201
}
214202

203+
/** Gets a string representation of a type returned by `getErasedRepr`. */
204+
string ppReprType(Type t) {
205+
if t.(BoxedType).getPrimitiveType().getName() = "double"
206+
then result = "Number"
207+
else result = t.toString()
208+
}
209+
215210
private predicate canContainBool(Type t) {
216211
t instanceof BooleanType or
217212
any(BooleanType b).(RefType).getASourceSupertype+() = t
@@ -227,12 +222,9 @@ predicate compatibleTypes(Type t1, Type t2) {
227222
e1 = getErasedRepr(t1) and
228223
e2 = getErasedRepr(t2)
229224
|
230-
/*
231-
* Because of `getErasedRepr`, `erasedHaveIntersection` is a sufficient
232-
* compatibility check, but `conContainBool` is kept as a dummy disjunct
233-
* to get the proper join-order.
234-
*/
235-
225+
// Because of `getErasedRepr`, `erasedHaveIntersection` is a sufficient
226+
// compatibility check, but `conContainBool` is kept as a dummy disjunct
227+
// to get the proper join-order.
236228
erasedHaveIntersection(e1, e2)
237229
or
238230
canContainBool(e1) and canContainBool(e2)

0 commit comments

Comments
 (0)