Merge pull request #19442 from hvitved/rust/clone-modeling

Rust: Strengthen modeling of the `Clone` trait
This commit is contained in:
Tom Hvitved
2025-05-01 17:11:42 +02:00
committed by GitHub
6 changed files with 9 additions and 33 deletions

View File

@@ -18,9 +18,7 @@ final class CloneCallable extends SummarizedCallable::Range {
final override predicate propagatesFlow(
string input, string output, boolean preservesValue, string model
) {
// The `clone` method takes a `&self` parameter and dereferences it;
// make sure to not clone the reference itself
input = ["Argument[self].Reference", "Argument[self].WithoutReference"] and
input = "Argument[self].Reference" and
output = "ReturnValue" and
preservesValue = true and
model = "generated"

View File

@@ -1041,8 +1041,8 @@ private module Debug {
private Locatable getRelevantLocatable() {
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
filepath.matches("%/tauri/src/app/plugin.rs") and
startline = 54
filepath.matches("%/main.rs") and
startline = 28
)
}

View File

@@ -10,7 +10,6 @@ edges
| main.rs:12:9:12:9 | a [Some] | main.rs:13:10:13:19 | a.unwrap() | provenance | MaD:2 |
| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:13 | a [Some] | provenance | |
| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | MaD:1 |
| main.rs:12:9:12:9 | a [Some] | main.rs:14:13:14:21 | a.clone() [Some] | provenance | generated |
| main.rs:12:13:12:28 | Some(...) [Some] | main.rs:12:9:12:9 | a [Some] | provenance | |
| main.rs:12:18:12:27 | source(...) | main.rs:12:13:12:28 | Some(...) [Some] | provenance | |
| main.rs:14:9:14:9 | b [Some] | main.rs:15:10:15:19 | b.unwrap() | provenance | MaD:2 |
@@ -19,29 +18,19 @@ edges
| main.rs:19:9:19:9 | a [Ok] | main.rs:20:10:20:19 | a.unwrap() | provenance | MaD:5 |
| main.rs:19:9:19:9 | a [Ok] | main.rs:21:13:21:13 | a [Ok] | provenance | |
| main.rs:19:9:19:9 | a [Ok] | main.rs:21:13:21:21 | a.clone() [Ok] | provenance | MaD:4 |
| main.rs:19:9:19:9 | a [Ok] | main.rs:21:13:21:21 | a.clone() [Ok] | provenance | generated |
| main.rs:19:31:19:44 | Ok(...) [Ok] | main.rs:19:9:19:9 | a [Ok] | provenance | |
| main.rs:19:34:19:43 | source(...) | main.rs:19:31:19:44 | Ok(...) [Ok] | provenance | |
| main.rs:21:9:21:9 | b [Ok] | main.rs:22:10:22:19 | b.unwrap() | provenance | MaD:5 |
| main.rs:21:13:21:13 | a [Ok] | main.rs:21:13:21:21 | a.clone() [Ok] | provenance | generated |
| main.rs:21:13:21:21 | a.clone() [Ok] | main.rs:21:9:21:9 | b [Ok] | provenance | |
| main.rs:26:9:26:9 | a | main.rs:27:10:27:10 | a | provenance | |
| main.rs:26:9:26:9 | a | main.rs:28:13:28:21 | a.clone() | provenance | generated |
| main.rs:26:13:26:22 | source(...) | main.rs:26:9:26:9 | a | provenance | |
| main.rs:28:9:28:9 | b | main.rs:29:10:29:10 | b | provenance | |
| main.rs:28:13:28:21 | a.clone() | main.rs:28:9:28:9 | b | provenance | |
| main.rs:41:13:41:13 | w [Wrapper] | main.rs:42:15:42:15 | w [Wrapper] | provenance | |
| main.rs:41:17:41:41 | Wrapper {...} [Wrapper] | main.rs:41:13:41:13 | w [Wrapper] | provenance | |
| main.rs:41:30:41:39 | source(...) | main.rs:41:17:41:41 | Wrapper {...} [Wrapper] | provenance | |
| main.rs:42:15:42:15 | w [Wrapper] | main.rs:43:13:43:28 | Wrapper {...} [Wrapper] | provenance | |
| main.rs:42:15:42:15 | w [Wrapper] | main.rs:45:17:45:25 | w.clone() [Wrapper] | provenance | generated |
| main.rs:43:13:43:28 | Wrapper {...} [Wrapper] | main.rs:43:26:43:26 | n | provenance | |
| main.rs:43:26:43:26 | n | main.rs:43:38:43:38 | n | provenance | |
| main.rs:45:13:45:13 | u [Wrapper] | main.rs:46:15:46:15 | u [Wrapper] | provenance | |
| main.rs:45:17:45:25 | w.clone() [Wrapper] | main.rs:45:13:45:13 | u [Wrapper] | provenance | |
| main.rs:46:15:46:15 | u [Wrapper] | main.rs:47:13:47:28 | Wrapper {...} [Wrapper] | provenance | |
| main.rs:47:13:47:28 | Wrapper {...} [Wrapper] | main.rs:47:26:47:26 | n | provenance | |
| main.rs:47:26:47:26 | n | main.rs:47:38:47:38 | n | provenance | |
| main.rs:58:13:58:13 | b [Some] | main.rs:59:23:59:23 | b [Some] | provenance | |
| main.rs:58:17:58:32 | Some(...) [Some] | main.rs:58:13:58:13 | b [Some] | provenance | |
| main.rs:58:22:58:31 | source(...) | main.rs:58:17:58:32 | Some(...) [Some] | provenance | |
@@ -75,9 +64,6 @@ nodes
| main.rs:26:9:26:9 | a | semmle.label | a |
| main.rs:26:13:26:22 | source(...) | semmle.label | source(...) |
| main.rs:27:10:27:10 | a | semmle.label | a |
| main.rs:28:9:28:9 | b | semmle.label | b |
| main.rs:28:13:28:21 | a.clone() | semmle.label | a.clone() |
| main.rs:29:10:29:10 | b | semmle.label | b |
| main.rs:41:13:41:13 | w [Wrapper] | semmle.label | w [Wrapper] |
| main.rs:41:17:41:41 | Wrapper {...} [Wrapper] | semmle.label | Wrapper {...} [Wrapper] |
| main.rs:41:30:41:39 | source(...) | semmle.label | source(...) |
@@ -85,12 +71,6 @@ nodes
| main.rs:43:13:43:28 | Wrapper {...} [Wrapper] | semmle.label | Wrapper {...} [Wrapper] |
| main.rs:43:26:43:26 | n | semmle.label | n |
| main.rs:43:38:43:38 | n | semmle.label | n |
| main.rs:45:13:45:13 | u [Wrapper] | semmle.label | u [Wrapper] |
| main.rs:45:17:45:25 | w.clone() [Wrapper] | semmle.label | w.clone() [Wrapper] |
| main.rs:46:15:46:15 | u [Wrapper] | semmle.label | u [Wrapper] |
| main.rs:47:13:47:28 | Wrapper {...} [Wrapper] | semmle.label | Wrapper {...} [Wrapper] |
| main.rs:47:26:47:26 | n | semmle.label | n |
| main.rs:47:38:47:38 | n | semmle.label | n |
| main.rs:58:13:58:13 | b [Some] | semmle.label | b [Some] |
| main.rs:58:17:58:32 | Some(...) [Some] | semmle.label | Some(...) [Some] |
| main.rs:58:22:58:31 | source(...) | semmle.label | source(...) |
@@ -114,8 +94,6 @@ testFailures
| main.rs:20:10:20:19 | a.unwrap() | main.rs:19:34:19:43 | source(...) | main.rs:20:10:20:19 | a.unwrap() | $@ | main.rs:19:34:19:43 | source(...) | source(...) |
| main.rs:22:10:22:19 | b.unwrap() | main.rs:19:34:19:43 | source(...) | main.rs:22:10:22:19 | b.unwrap() | $@ | main.rs:19:34:19:43 | source(...) | source(...) |
| main.rs:27:10:27:10 | a | main.rs:26:13:26:22 | source(...) | main.rs:27:10:27:10 | a | $@ | main.rs:26:13:26:22 | source(...) | source(...) |
| main.rs:29:10:29:10 | b | main.rs:26:13:26:22 | source(...) | main.rs:29:10:29:10 | b | $@ | main.rs:26:13:26:22 | source(...) | source(...) |
| main.rs:43:38:43:38 | n | main.rs:41:30:41:39 | source(...) | main.rs:43:38:43:38 | n | $@ | main.rs:41:30:41:39 | source(...) | source(...) |
| main.rs:47:38:47:38 | n | main.rs:41:30:41:39 | source(...) | main.rs:47:38:47:38 | n | $@ | main.rs:41:30:41:39 | source(...) | source(...) |
| main.rs:63:22:63:22 | m | main.rs:58:22:58:31 | source(...) | main.rs:63:22:63:22 | m | $@ | main.rs:58:22:58:31 | source(...) | source(...) |
| main.rs:85:18:85:34 | ...::read(...) | main.rs:84:32:84:41 | source(...) | main.rs:85:18:85:34 | ...::read(...) | $@ | main.rs:84:32:84:41 | source(...) | source(...) |

View File

@@ -26,7 +26,7 @@ fn i64_clone() {
let a = source(12);
sink(a); // $ hasValueFlow=12
let b = a.clone();
sink(b); // $ hasValueFlow=12
sink(b); // $ MISSING: hasValueFlow=12 - lack of builtins means that we cannot resolve clone call above, and hence not insert implicit borrow
}
mod my_clone {
@@ -44,7 +44,7 @@ mod my_clone {
}
let u = w.clone();
match u {
Wrapper { n: n } => sink(n), // $ hasValueFlow=73
Wrapper { n: n } => sink(n), // $ MISSING: hasValueFlow=73 - lack of expanded derives means that we cannot resolve clone call above, and hence not insert implicit borrow
}
}
}

View File

@@ -1,4 +1,4 @@
unexpectedModel
| Unexpected summary found: repo::test;<crate::option::MyOption as crate::clone::Clone>::clone;Argument[self].Field[crate::option::MyOption::MySome(0)].Reference;ReturnValue.Field[crate::option::MyOption::MySome(0)];value;dfc-generated |
| Unexpected summary found: repo::test;<crate::option::MyOption>::cloned;Argument[self].Field[crate::option::MyOption::MySome(0)].Reference;ReturnValue.Field[crate::option::MyOption::MySome(0)];value;dfc-generated |
expectedModel
| Expected summary missing: repo::test;<crate::option::MyOption as crate::clone::Clone>::clone;Argument[self].Reference.Field[crate::option::MyOption::MySome(0)];ReturnValue.Field[crate::option::MyOption::MySome(0)];value;dfc-generated |

View File

@@ -414,7 +414,7 @@ impl<T> MyOption<&T> {
}
}
// summary=repo::test;<crate::option::MyOption>::cloned;Argument[self].Field[crate::option::MyOption::MySome(0)];ReturnValue.Field[crate::option::MyOption::MySome(0)];value;dfc-generated
// summary=repo::test;<crate::option::MyOption>::cloned;Argument[self].Field[crate::option::MyOption::MySome(0)].Reference;ReturnValue.Field[crate::option::MyOption::MySome(0)];value;dfc-generated
pub fn cloned(self) -> MyOption<T>
where
T: Clone,
@@ -438,7 +438,7 @@ impl<T> MyOption<&mut T> {
}
}
// summary=repo::test;<crate::option::MyOption>::cloned;Argument[self].Field[crate::option::MyOption::MySome(0)];ReturnValue.Field[crate::option::MyOption::MySome(0)];value;dfc-generated
// summary=repo::test;<crate::option::MyOption>::cloned;Argument[self].Field[crate::option::MyOption::MySome(0)].Reference;ReturnValue.Field[crate::option::MyOption::MySome(0)];value;dfc-generated
pub fn cloned(self) -> MyOption<T>
where
T: Clone,
@@ -466,7 +466,7 @@ impl<T> Clone for MyOption<T>
where
T: Clone,
{
// summary=repo::test;<crate::option::MyOption as crate::clone::Clone>::clone;Argument[self].Field[crate::option::MyOption::MySome(0)];ReturnValue.Field[crate::option::MyOption::MySome(0)];value;dfc-generated
// summary=repo::test;<crate::option::MyOption as crate::clone::Clone>::clone;Argument[self].Reference.Field[crate::option::MyOption::MySome(0)];ReturnValue.Field[crate::option::MyOption::MySome(0)];value;dfc-generated
fn clone(&self) -> Self {
match self {
MySome(x) => MySome(x.clone()),