FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Rust: Data flow through trait methods by hvitved · Pull Request #19881 · github/codeql · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .expected  (4) .list  (1) .md  (1) .qll  (5) .rs  (2) .yml  (1) dotfile  (1) All 7 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
1 change: 0 additions & 1 deletion rust/ql/.generated.list

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion rust/ql/.gitattributes

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Implemented support for data flow through trait functions. For the purpose of data flow, calls to trait functions dispatch to all possible implementations.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,20 @@ module RustDataFlow implements InputSig<Location> {

/** Gets a viable implementation of the target of the given `Call`. */
DataFlowCallable viableCallable(DataFlowCall call) {

Copilot AI Jun 26, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

[nitpick] The viableCallable definition contains deeply nested exists and or expressions; extracting the trait-dispatch logic into a helper predicate could improve readability and maintenance.

Copilot uses AI. Check for mistakes.
exists(Callable target | target = call.asCallCfgNode().getCall().getStaticTarget() |
target = result.asCfgScope()
exists(Call c | c = call.asCallCfgNode().getCall() |
result.asCfgScope() = c.getARuntimeTarget()
or
target = result.asSummarizedCallable()
exists(SummarizedCallable sc, Function staticTarget |
staticTarget = c.getStaticTarget() and
sc = result.asSummarizedCallable()
|
sc = staticTarget
or
// only apply trait models to concrete implementations when they are not
// defined in source code
staticTarget.implements(sc) and
not staticTarget.fromSource()
)
)
}

Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
* - `Field[t(i)]`: position `i` inside the variant/struct with canonical path `v`, for example
* `Field[core::option::Option::Some(0)]`.
* - `Field[i]`: the `i`th element of a tuple.
* - `Reference`: the referenced value.
* - `Future`: the value being computed asynchronously.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Good spot. 👍

* 3. The `kind` column is a tag that can be referenced from QL to determine to
* which classes the interpreted elements should be added. For example, for
* sources `"remote"` indicates a default remote flow source, and for summaries
Expand Down Expand Up @@ -211,6 +213,10 @@ private class SummarizedCallableFromModel extends SummarizedCallable::Range {
this.getCanonicalPath() = path
}

override predicate hasProvenance(Provenance provenance) {
summaryModel(path, _, _, _, provenance, _)
}

override predicate propagatesFlow(
string input, string output, boolean preservesValue, string model
) {
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// generated by codegen, remove this comment if you wish to edit this file
/**
* This module provides a hand-modifiable wrapper around the generated class `AssocItem`.
*
Expand All @@ -12,6 +11,10 @@ private import codeql.rust.elements.internal.generated.AssocItem
* be referenced directly.
*/
module Impl {
private import rust
private import codeql.rust.internal.PathResolution

// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* An associated item in a `Trait` or `Impl`.
*
Expand All @@ -21,5 +24,15 @@ module Impl {
* // ^^^^^^^^^^^^^
* ```
*/
class AssocItem extends Generated::AssocItem { }
class AssocItem extends Generated::AssocItem {
/** Holds if this item implements trait item `other`. */
pragma[nomagic]
predicate implements(AssocItem other) {
exists(TraitItemNode t, ImplItemNode i, string name |
other = t.getAssocItem(pragma[only_bind_into](name)) and
t = i.resolveTraitTy() and
this = i.getAssocItem(pragma[only_bind_into](name))
)
}
}
}
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ module Impl {
not exists(TypeInference::resolveMethodCallTarget(this)) and
result = this.(CallExpr).getStaticTarget()
}

/** Gets a runtime target of this call, if any. */
pragma[nomagic]
Function getARuntimeTarget() {
result.hasImplementation() and
(
result = this.getStaticTarget()
or
result.implements(this.getStaticTarget())
)
}
}

/** Holds if the call expression dispatches to a trait method. */
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,13 @@ abstract class ImplOrTraitItemNode extends ItemNode {
/** Gets an associated item belonging to this trait or `impl` block. */
abstract AssocItemNode getAnAssocItem();

/** Gets the associated item named `name` belonging to this trait or `impl` block. */
pragma[nomagic]
AssocItemNode getAssocItem(string name) {
result = this.getAnAssocItem() and
result.getName() = name
}

/** Holds if this trait or `impl` block declares an associated item named `name`. */
pragma[nomagic]
predicate hasAssocItem(string name) { name = this.getAnAssocItem().getName() }
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
multipleCallTargets
| main.rs:225:14:225:29 | ...::deref(...) |
| main.rs:272:14:272:29 | ...::deref(...) |
Loading

Back | FazBrowse Home | New Git URL