Skip to content

Commit 8619422

Browse files
authored
Merge pull request #4891 from MathiasVP/get-an-overload-perf-fix
C++: Fix join order in getAnOverload
2 parents 6d973d0 + 134982c commit 8619422

File tree

1 file changed

+34
-11
lines changed

1 file changed

+34
-11
lines changed

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

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -391,20 +391,30 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
391391
/** Holds if this function has a `noexcept` exception specification. */
392392
predicate isNoExcept() { getADeclarationEntry().isNoExcept() }
393393

394-
/** Gets a function that overloads this one. */
394+
/**
395+
* Gets a function that overloads this one.
396+
*
397+
* Note: if _overrides_ are wanted rather than _overloads_ then
398+
* `MemberFunction::getAnOverridingFunction` should be used instead.
399+
*/
395400
Function getAnOverload() {
396-
result.getName() = getName() and
397-
result.getNamespace() = getNamespace() and
398-
result != this and
399-
// If this function is declared in a class, only consider other
400-
// functions from the same class. Conversely, if this function is not
401-
// declared in a class, only consider other functions not declared in a
402-
// class.
403401
(
404-
if exists(getDeclaringType())
405-
then result.getDeclaringType() = getDeclaringType()
406-
else not exists(result.getDeclaringType())
402+
// If this function is declared in a class, only consider other
403+
// functions from the same class.
404+
exists(string name, Class declaringType |
405+
candGetAnOverloadMember(name, declaringType, this) and
406+
candGetAnOverloadMember(name, declaringType, result)
407+
)
408+
or
409+
// Conversely, if this function is not
410+
// declared in a class, only consider other functions not declared in a
411+
// class.
412+
exists(string name, Namespace namespace |
413+
candGetAnOverloadNonMember(name, namespace, this) and
414+
candGetAnOverloadNonMember(name, namespace, result)
415+
)
407416
) and
417+
result != this and
408418
// Instantiations and specializations don't participate in overload
409419
// resolution.
410420
not (
@@ -462,6 +472,19 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
462472
override AccessHolder getEnclosingAccessHolder() { result = this.getDeclaringType() }
463473
}
464474

475+
pragma[noinline]
476+
private predicate candGetAnOverloadMember(string name, Class declaringType, Function f) {
477+
f.getName() = name and
478+
f.getDeclaringType() = declaringType
479+
}
480+
481+
pragma[noinline]
482+
private predicate candGetAnOverloadNonMember(string name, Namespace namespace, Function f) {
483+
f.getName() = name and
484+
f.getNamespace() = namespace and
485+
not exists(f.getDeclaringType())
486+
}
487+
465488
/**
466489
* A particular declaration or definition of a C/C++ function. For example the
467490
* declaration and definition of `MyFunction` in the following code are each a

0 commit comments

Comments
 (0)