diff --git a/rust/ql/consistency-queries/DataFlowConsistency.ql b/rust/ql/consistency-queries/DataFlowConsistency.ql index 3513121f2608..ed50c3876aa9 100644 --- a/rust/ql/consistency-queries/DataFlowConsistency.ql +++ b/rust/ql/consistency-queries/DataFlowConsistency.ql @@ -5,12 +5,4 @@ * @id rust/diagnostics/data-flow-consistency */ -import codeql.rust.dataflow.DataFlow::DataFlow as DataFlow -private import rust -private import codeql.rust.dataflow.internal.DataFlowImpl -private import codeql.rust.dataflow.internal.TaintTrackingImpl -private import codeql.dataflow.internal.DataFlowImplConsistency - -private module Input implements InputSig { } - -import MakeConsistency +import codeql.rust.dataflow.internal.DataFlowConsistency diff --git a/rust/ql/lib/codeql/rust/AstConsistency.qll b/rust/ql/lib/codeql/rust/AstConsistency.qll index 3902f56d20ba..2358bddb3b9d 100644 --- a/rust/ql/lib/codeql/rust/AstConsistency.qll +++ b/rust/ql/lib/codeql/rust/AstConsistency.qll @@ -21,6 +21,11 @@ query predicate multipleToStrings(Element e, string cls, string s) { */ query predicate multipleLocations(Locatable e) { strictcount(e.getLocation()) > 1 } +/** + * Holds if `e` does not have a `Location`. + */ +query predicate noLocation(Locatable e) { not exists(e.getLocation()) } + private predicate multiplePrimaryQlClasses(Element e) { strictcount(string cls | cls = e.getAPrimaryQlClass() and cls != "VariableAccess") > 1 } @@ -58,6 +63,9 @@ int getAstInconsistencyCounts(string type) { type = "Multiple locations" and result = count(Element e | multipleLocations(e) | e) or + type = "No location" and + result = count(Element e | noLocation(e) | e) + or type = "Multiple primary QL classes" and result = count(Element e | multiplePrimaryQlClasses(e) | e) or diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowConsistency.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowConsistency.qll new file mode 100644 index 000000000000..17b74ee28845 --- /dev/null +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowConsistency.qll @@ -0,0 +1,17 @@ +import codeql.rust.dataflow.DataFlow::DataFlow as DataFlow +private import rust +private import codeql.rust.dataflow.internal.DataFlowImpl +private import codeql.rust.dataflow.internal.TaintTrackingImpl +private import codeql.dataflow.internal.DataFlowImplConsistency + +private module Input implements InputSig { + predicate uniqueNodeLocationExclude(RustDataFlow::Node n) { + // Exclude nodes where the missing location can be explained by the + // underlying AST node not having a location. + not exists(n.asExpr().getLocation()) + } + + predicate missingLocationExclude(RustDataFlow::Node n) { not exists(n.asExpr().getLocation()) } +} + +import MakeConsistency diff --git a/rust/ql/src/queries/diagnostics/DataFlowConsistencyCounts.ql b/rust/ql/src/queries/diagnostics/DataFlowConsistencyCounts.ql index 79c582adb08d..ecc7d1eb55a6 100644 --- a/rust/ql/src/queries/diagnostics/DataFlowConsistencyCounts.ql +++ b/rust/ql/src/queries/diagnostics/DataFlowConsistencyCounts.ql @@ -5,17 +5,10 @@ * @id rust/diagnostics/data-flow-consistency-counts */ -private import rust -private import codeql.rust.dataflow.internal.DataFlowImpl -private import codeql.rust.dataflow.internal.TaintTrackingImpl -private import codeql.dataflow.internal.DataFlowImplConsistency - -private module Input implements InputSig { } +import codeql.rust.dataflow.internal.DataFlowConsistency as Consistency // see also `rust/diagnostics/data-flow-consistency`, which lists the // individual inconsistency results. from string type, int num -where - num = - MakeConsistency::getInconsistencyCounts(type) +where num = Consistency::getInconsistencyCounts(type) select type, num diff --git a/rust/ql/src/queries/summary/Stats.qll b/rust/ql/src/queries/summary/Stats.qll index aec671098eb1..c2993b47899f 100644 --- a/rust/ql/src/queries/summary/Stats.qll +++ b/rust/ql/src/queries/summary/Stats.qll @@ -7,7 +7,7 @@ private import codeql.rust.dataflow.internal.DataFlowImpl private import codeql.rust.dataflow.internal.TaintTrackingImpl private import codeql.rust.AstConsistency as AstConsistency private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency -private import codeql.dataflow.internal.DataFlowImplConsistency as DataFlowImplConsistency +private import codeql.rust.dataflow.internal.DataFlowConsistency as DataFlowConsistency /** * Gets a count of the total number of lines of code in the database. @@ -35,15 +35,9 @@ int getTotalCfgInconsistencies() { result = sum(string type | | CfgConsistency::getCfgInconsistencyCounts(type)) } -private module Input implements DataFlowImplConsistency::InputSig { } - /** * Gets a count of the total number of data flow inconsistencies in the database. */ int getTotalDataFlowInconsistencies() { - result = - sum(string type | - | - DataFlowImplConsistency::MakeConsistency::getInconsistencyCounts(type) - ) + result = sum(string type | | DataFlowConsistency::getInconsistencyCounts(type)) } diff --git a/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/AstConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/AstConsistency.expected new file mode 100644 index 000000000000..f0508f1853fe --- /dev/null +++ b/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/AstConsistency.expected @@ -0,0 +1,42 @@ +noLocation +| file://:0:0:0:0 | ... .parent(...) | +| file://:0:0:0:0 | ... .unwrap(...) | +| file://:0:0:0:0 | ...: ... | +| file://:0:0:0:0 | ...::Path | +| file://:0:0:0:0 | ...::path | +| file://:0:0:0:0 | ArgList | +| file://:0:0:0:0 | ArgList | +| file://:0:0:0:0 | MacroItems | +| file://:0:0:0:0 | ParamList | +| file://:0:0:0:0 | Path | +| file://:0:0:0:0 | Path | +| file://:0:0:0:0 | Path | +| file://:0:0:0:0 | Path | +| file://:0:0:0:0 | Path | +| file://:0:0:0:0 | Path | +| file://:0:0:0:0 | Path | +| file://:0:0:0:0 | Path | +| file://:0:0:0:0 | Path | +| file://:0:0:0:0 | Path | +| file://:0:0:0:0 | RefType | +| file://:0:0:0:0 | RefType | +| file://:0:0:0:0 | RetType | +| file://:0:0:0:0 | StmtList | +| file://:0:0:0:0 | Use | +| file://:0:0:0:0 | UseTree | +| file://:0:0:0:0 | fn get_parent | +| file://:0:0:0:0 | get_parent | +| file://:0:0:0:0 | parent | +| file://:0:0:0:0 | path | +| file://:0:0:0:0 | path | +| file://:0:0:0:0 | path | +| file://:0:0:0:0 | path | +| file://:0:0:0:0 | path | +| file://:0:0:0:0 | path | +| file://:0:0:0:0 | path | +| file://:0:0:0:0 | path | +| file://:0:0:0:0 | std | +| file://:0:0:0:0 | std | +| file://:0:0:0:0 | std | +| file://:0:0:0:0 | unwrap | +| file://:0:0:0:0 | { ... } | diff --git a/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected b/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected deleted file mode 100644 index 28012e97348f..000000000000 --- a/rust/ql/test/extractor-tests/generated/MacroItems/CONSISTENCY/DataFlowConsistency.expected +++ /dev/null @@ -1,11 +0,0 @@ -uniqueNodeLocation -| file://:0:0:0:0 | ... .parent(...) | Node should have one location but has 0. | -| file://:0:0:0:0 | ... .parent(...) | Node should have one location but has 0. | -| file://:0:0:0:0 | ... .unwrap(...) | Node should have one location but has 0. | -| file://:0:0:0:0 | ...: ... | Node should have one location but has 0. | -| file://:0:0:0:0 | path | Node should have one location but has 0. | -| file://:0:0:0:0 | path | Node should have one location but has 0. | -| file://:0:0:0:0 | path | Node should have one location but has 0. | -| file://:0:0:0:0 | { ... } | Node should have one location but has 0. | -missingLocation -| Nodes without location: 8 | diff --git a/rust/ql/test/query-tests/diagnostics/AstConsistencyCounts.expected b/rust/ql/test/query-tests/diagnostics/AstConsistencyCounts.expected index 62ee879ab1eb..72147226e42b 100644 --- a/rust/ql/test/query-tests/diagnostics/AstConsistencyCounts.expected +++ b/rust/ql/test/query-tests/diagnostics/AstConsistencyCounts.expected @@ -2,3 +2,4 @@ | Multiple parents | 0 | | Multiple primary QL classes | 0 | | Multiple toStrings | 0 | +| No location | 0 |