From 4e46b0e668c372c0d5002e2dc183d6e1f38dc8fa Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 4 Oct 2024 10:30:36 +0100 Subject: [PATCH] Avoid pathological case where getExampleMethodName picks a very common method name --- go/ql/lib/semmle/go/Types.qll | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/go/ql/lib/semmle/go/Types.qll b/go/ql/lib/semmle/go/Types.qll index d71869aa995c2..12236d73dad98 100644 --- a/go/ql/lib/semmle/go/Types.qll +++ b/go/ql/lib/semmle/go/Types.qll @@ -1064,10 +1064,19 @@ class ErrorType extends Type { ErrorType() { this.implements(Builtin::error().getType().getUnderlyingType()) } } +/** + * Gets the number of types with method `name`. + */ +bindingset[name] +int numberOfTypesWithMethodName(string name) { result = count(Type t | t.hasMethod(name, _)) } + /** * Gets the name of a method in the method set of `i`. * * This is used to restrict the set of interfaces to consider in the definition of `implements`, - * so it does not matter which method name is chosen (we use the lexicographically least). + * so it does not matter which method name is chosen (we use the most unusual name the interface + * require; this is the most discriminating and so shrinks the search space the most). */ -private string getExampleMethodName(InterfaceType i) { result = min(string m | i.hasMethod(m, _)) } +private string getExampleMethodName(InterfaceType i) { + result = min(string m | i.hasMethod(m, _) | m order by numberOfTypesWithMethodName(m)) +}