Skip to content

Commit 315afd3

Browse files
committed
Improve efficiency of composite-type deep-unalias computation
1 parent 4da5cd9 commit 315afd3

File tree

1 file changed

+51
-11
lines changed

1 file changed

+51
-11
lines changed

go/ql/lib/semmle/go/Types.qll

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -602,12 +602,25 @@ class StructType extends @structtype, CompositeType {
602602
component_types(this, i, name, tp) and component_tags(this, i, tag)
603603
}
604604

605-
override StructType getDeepUnaliasedType() {
605+
private predicate isDeepUnaliasedTypeUpTo(StructType unaliased, int i) {
606606
// Note we must use component_types not hasOwnField here because component_types may specify
607607
// interface-in-struct embedding, but hasOwnField does not return such members.
608-
count(int i | component_types(this, i, _, _)) = count(int i | component_types(result, i, _, _)) and
609-
forall(int i, string name, Type tp, string tag | this.hasComponentTypeAndTag(i, name, tp, tag) |
610-
result.hasComponentTypeAndTag(i, name, tp.getDeepUnaliasedType(), tag)
608+
(
609+
i = 0 or
610+
this.isDeepUnaliasedTypeUpTo(unaliased, i - 1)
611+
) and
612+
exists(string name, Type tp, string tag | this.hasComponentTypeAndTag(i, name, tp, tag) |
613+
unaliased.hasComponentTypeAndTag(i, name, tp.getDeepUnaliasedType(), tag)
614+
)
615+
}
616+
617+
override StructType getDeepUnaliasedType() {
618+
exists(int nComponents | nComponents = count(int i | component_types(this, i, _, _)) |
619+
(
620+
this.isDeepUnaliasedTypeUpTo(result, nComponents - 1)
621+
or
622+
nComponents = 0 and result = this
623+
)
611624
)
612625
}
613626

@@ -938,10 +951,21 @@ class TupleType extends @tupletype, CompositeType {
938951
/** Gets the `i`th component type of this tuple type. */
939952
Type getComponentType(int i) { component_types(this, i, _, result) }
940953

954+
private predicate isDeepUnaliasedTypeUpTo(TupleType tt, int i) {
955+
tt.getComponentType(i) = this.getDeepUnaliasedType() and
956+
(
957+
i = 0
958+
or
959+
this.isDeepUnaliasedTypeUpTo(tt, i - 1)
960+
)
961+
}
962+
941963
override TupleType getDeepUnaliasedType() {
942-
count(int i | component_types(this, i, _, _)) = count(int i | component_types(result, i, _, _)) and
943-
forall(Type t, int i | t = this.getComponentType(i) |
944-
result.getComponentType(i) = t.getDeepUnaliasedType()
964+
exists(int nComponents | nComponents = count(int i | exists(this.getComponentType(i))) |
965+
this.isDeepUnaliasedTypeUpTo(result, nComponents - 1)
966+
or
967+
// I don't think Go allows empty tuples in any context, but this is at least harmless.
968+
nComponents = 0 and result = this
945969
)
946970
}
947971

@@ -971,15 +995,31 @@ class SignatureType extends @signaturetype, CompositeType {
971995
/** Holds if this signature type is variadic. */
972996
predicate isVariadic() { variadic(this) }
973997

998+
private predicate hasDeepUnaliasedParameterTypesUpTo(SignatureType unaliased, int i) {
999+
(i = 0 or this.hasDeepUnaliasedParameterTypesUpTo(unaliased, i - 1)) and
1000+
unaliased.getParameterType(i) = this.getParameterType(i).getDeepUnaliasedType()
1001+
}
1002+
1003+
private predicate hasDeepUnaliasedResultTypesUpTo(SignatureType unaliased, int i) {
1004+
(i = 0 or this.hasDeepUnaliasedResultTypesUpTo(unaliased, i - 1)) and
1005+
unaliased.getResultType(i) = this.getResultType(i).getDeepUnaliasedType()
1006+
}
1007+
9741008
override SignatureType getDeepUnaliasedType() {
975-
count(int i | component_types(this, i, _, _)) = count(int i | component_types(result, i, _, _)) and
1009+
exists(int nParams | nParams = this.getNumParameter() |
1010+
nParams = 0 and result.getNumParameter() = 0
1011+
or
1012+
this.hasDeepUnaliasedParameterTypesUpTo(result, nParams - 1)
1013+
) and
1014+
exists(int nResults | nResults = this.getNumResult() |
1015+
nResults = 0 and result.getNumResult() = 0
1016+
or
1017+
this.hasDeepUnaliasedResultTypesUpTo(result, nResults - 1)
1018+
) and
9761019
(
9771020
this.isVariadic() and result.isVariadic()
9781021
or
9791022
not this.isVariadic() and not result.isVariadic()
980-
) and
981-
forall(int i, Type componentType | component_types(this, i, _, componentType) |
982-
component_types(result, i, _, componentType.getDeepUnaliasedType())
9831023
)
9841024
}
9851025

0 commit comments

Comments
 (0)