Skip to content

Commit 7eca4b4

Browse files
committed
C++: Fix join-order problem with isBefore
Reported here: github#17743 Without this change on the query provided by the user: ``` [2025-02-25 12:42:01] Evaluated non-recursive predicate quickquery::UnrealFunctionAnnotation.annotates/1#dispred#9cd6c269@c668c8tv in 23846ms (size: 20381473). Evaluated relational algebra for predicate quickquery::UnrealFunctionAnnotation.annotates/1#dispred#9cd6c269@c668c8tv with tuple counts: 1 ~0% {0} r1 = CONSTANT()[] 27323 ~0% {2} | JOIN WITH `Location::Location.getEndLine/0#dispred#83af84ae#bf` CARTESIAN PRODUCT OUTPUT Rhs.0, Rhs.1 6162566035 ~0% {4} | JOIN WITH `Location::Location.getStartLine/0#d54f9e6c` CARTESIAN PRODUCT OUTPUT Lhs.0, Lhs.1, Rhs.0, Rhs.1 {4} | REWRITE WITH TEST InOut.1 < InOut.3 3894825644 ~5% {2} | SCAN OUTPUT In.2, In.0 73148692 ~0% {3} | JOIN WITH fun_decls_40#join_rhs ON FIRST 1 OUTPUT Lhs.1, Lhs.0, Rhs.1 73148692 ~0% {4} | JOIN WITH `Location::Location.getFile/0#dispred#d1f8b5d1` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.0, Lhs.2 864579 ~0% {2} | JOIN WITH `Location::Location.getFile/0#dispred#d1f8b5d1` ON FIRST 2 OUTPUT Lhs.2, Lhs.3 13010742 ~1% {2} | JOIN WITH macroinvocations_20#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 20653781 ~0% {3} | JOIN WITH `Macro::MacroAccess.getOutermostMacroAccess/0#d58b05db_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, _, Lhs.1 20653781 ~4% {3} | REWRITE WITH Out.1 := 1 20381473 ~8% {2} | JOIN WITH macroinvocations_03#join_rhs ON FIRST 2 OUTPUT Lhs.0, Lhs.2 return r1 ``` With this change: ``` [2025-02-25 12:43:10] Evaluated non-recursive predicate quickquery::UnrealFunctionAnnotation.annotates/1#dispred#9cd6c269@11bf8956 in 928ms (size: 20381473). Evaluated relational algebra for predicate quickquery::UnrealFunctionAnnotation.annotates/1#dispred#9cd6c269@11bf8956 with tuple counts: 6873 ~3% {2} r1 = SCAN fun_decls OUTPUT In.4, In.0 6857 ~0% {3} | JOIN WITH `Location::Location.getStartLine/0#d54f9e6c` ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Rhs.1 6857 ~2% {3} | JOIN WITH `Location::Location.getFile/0#dispred#d1f8b5d1` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2 6193961 ~0% {3} | JOIN WITH `Location::Location.getFile/0#dispred#d1f8b5d1_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2 27389714 ~1% {4} | JOIN WITH macroinvocations_20#join_rhs ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Rhs.1 27389714 ~1% {4} | JOIN WITH locations_default ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3, Rhs.4 {4} | REWRITE WITH TEST InOut.3 < InOut.1 13010742 ~1% {2} | SCAN OUTPUT In.2, In.0 20653781 ~0% {3} | JOIN WITH `Macro::MacroAccess.getOutermostMacroAccess/0#d58b05db_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, _, Lhs.1 20653781 ~4% {3} | REWRITE WITH Out.1 := 1 20381473 ~8% {2} | JOIN WITH macroinvocations_03#join_rhs ON FIRST 2 OUTPUT Lhs.0, Lhs.2 return r1 ```
1 parent f406914 commit 7eca4b4

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

cpp/ql/lib/semmle/code/cpp/Location.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ class Location extends @location {
7575

7676
/** Holds if `this` comes on a line strictly before `l`. */
7777
pragma[inline]
78-
predicate isBefore(Location l) { this.isBefore(l, false) }
78+
predicate isBefore(Location l) {
79+
this.getFile() = l.getFile() and
80+
this.getEndLine() < l.getStartLine()
81+
}
7982

8083
/**
8184
* Holds if `this` comes strictly before `l`. The boolean `sameLine` is

0 commit comments

Comments
 (0)