Skip to content

Commit ab74d90

Browse files
committed
Rust: Path resolution for inherited functions
1 parent f3a393f commit ab74d90

File tree

5 files changed

+48
-6
lines changed

5 files changed

+48
-6
lines changed

rust/ql/lib/codeql/rust/elements/internal/PathResolution.qll

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ abstract class ItemNode extends AstNode {
130130
call = this.getASuccessorRec(_) and
131131
result = call.(ItemNode).getASuccessorRec(name)
132132
)
133+
or
134+
// an inherited function, either from a trait bound or from an `impl` block
135+
exists(ItemNode node |
136+
result = node.(ItemNode).getASuccessorRec(name) and
137+
result instanceof Function
138+
|
139+
node = this.(TraitItemNode).resolveABound()
140+
or
141+
this = node.(ImplItemNode).resolveSelfTy()
142+
)
133143
}
134144

135145
/** Gets a successor named `name` of this item, if any. */
@@ -269,6 +279,13 @@ private class StructItemNode extends ItemNode instanceof Struct {
269279
}
270280

271281
class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
282+
pragma[nomagic]
283+
Path getABoundPath() {
284+
result = super.getTypeBoundList().getABound().getTypeRepr().(PathTypeRepr).getPath()
285+
}
286+
287+
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
288+
272289
override string getName() { result = Trait.super.getName().getText() }
273290

274291
override Namespace getNamespace() { result.isType() }

rust/ql/test/library-tests/dataflow/global/inline-flow.expected

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ edges
4242
| main.rs:103:13:103:30 | mn.data_through(...) | main.rs:103:9:103:9 | b | provenance | |
4343
| main.rs:103:29:103:29 | a | main.rs:79:28:79:33 | ...: i64 | provenance | |
4444
| main.rs:103:29:103:29 | a | main.rs:103:13:103:30 | mn.data_through(...) | provenance | |
45+
| main.rs:109:9:109:9 | a | main.rs:110:26:110:26 | a | provenance | |
46+
| main.rs:109:13:109:21 | source(...) | main.rs:109:9:109:9 | a | provenance | |
47+
| main.rs:110:26:110:26 | a | main.rs:67:23:67:28 | ...: i64 | provenance | |
48+
| main.rs:115:9:115:9 | a | main.rs:116:39:116:39 | a | provenance | |
49+
| main.rs:115:13:115:22 | source(...) | main.rs:115:9:115:9 | a | provenance | |
50+
| main.rs:116:9:116:9 | b | main.rs:117:10:117:10 | b | provenance | |
51+
| main.rs:116:13:116:40 | ...::data_through(...) | main.rs:116:9:116:9 | b | provenance | |
52+
| main.rs:116:39:116:39 | a | main.rs:79:28:79:33 | ...: i64 | provenance | |
53+
| main.rs:116:39:116:39 | a | main.rs:116:13:116:40 | ...::data_through(...) | provenance | |
4554
| main.rs:128:12:128:17 | ...: i64 | main.rs:129:24:129:24 | n | provenance | |
4655
| main.rs:129:9:129:26 | MyInt {...} [MyInt] | main.rs:128:28:130:5 | { ... } [MyInt] | provenance | |
4756
| main.rs:129:24:129:24 | n | main.rs:129:9:129:26 | MyInt {...} [MyInt] | provenance | |
@@ -130,6 +139,15 @@ nodes
130139
| main.rs:103:13:103:30 | mn.data_through(...) | semmle.label | mn.data_through(...) |
131140
| main.rs:103:29:103:29 | a | semmle.label | a |
132141
| main.rs:104:10:104:10 | b | semmle.label | b |
142+
| main.rs:109:9:109:9 | a | semmle.label | a |
143+
| main.rs:109:13:109:21 | source(...) | semmle.label | source(...) |
144+
| main.rs:110:26:110:26 | a | semmle.label | a |
145+
| main.rs:115:9:115:9 | a | semmle.label | a |
146+
| main.rs:115:13:115:22 | source(...) | semmle.label | source(...) |
147+
| main.rs:116:9:116:9 | b | semmle.label | b |
148+
| main.rs:116:13:116:40 | ...::data_through(...) | semmle.label | ...::data_through(...) |
149+
| main.rs:116:39:116:39 | a | semmle.label | a |
150+
| main.rs:117:10:117:10 | b | semmle.label | b |
133151
| main.rs:128:12:128:17 | ...: i64 | semmle.label | ...: i64 |
134152
| main.rs:128:28:130:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] |
135153
| main.rs:129:9:129:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] |
@@ -179,6 +197,7 @@ subpaths
179197
| main.rs:41:26:44:5 | { ... } | main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | main.rs:41:13:44:6 | pass_through(...) |
180198
| main.rs:55:26:55:26 | a | main.rs:51:21:51:26 | ...: i64 | main.rs:51:36:53:5 | { ... } | main.rs:55:13:55:27 | pass_through(...) |
181199
| main.rs:103:29:103:29 | a | main.rs:79:28:79:33 | ...: i64 | main.rs:79:43:85:5 | { ... } | main.rs:103:13:103:30 | mn.data_through(...) |
200+
| main.rs:116:39:116:39 | a | main.rs:79:28:79:33 | ...: i64 | main.rs:79:43:85:5 | { ... } | main.rs:116:13:116:40 | ...::data_through(...) |
182201
| main.rs:134:24:134:33 | source(...) | main.rs:128:12:128:17 | ...: i64 | main.rs:128:28:130:5 | { ... } [MyInt] | main.rs:134:13:134:34 | ...::new(...) [MyInt] |
183202
| main.rs:187:49:187:49 | a [MyInt] | main.rs:175:18:175:21 | SelfParam [MyInt] | main.rs:175:48:177:5 | { ... } [MyInt] | main.rs:187:30:187:53 | ...::take_self(...) [MyInt] |
184203
| main.rs:192:54:192:54 | b [MyInt] | main.rs:179:26:179:37 | ...: MyInt [MyInt] | main.rs:179:49:181:5 | { ... } [MyInt] | main.rs:192:30:192:55 | ...::take_second(...) [MyInt] |
@@ -191,8 +210,10 @@ testFailures
191210
| main.rs:45:10:45:10 | a | main.rs:43:9:43:18 | source(...) | main.rs:45:10:45:10 | a | $@ | main.rs:43:9:43:18 | source(...) | source(...) |
192211
| main.rs:56:10:56:10 | b | main.rs:49:13:49:22 | source(...) | main.rs:56:10:56:10 | b | $@ | main.rs:49:13:49:22 | source(...) | source(...) |
193212
| main.rs:68:14:68:14 | n | main.rs:96:13:96:21 | source(...) | main.rs:68:14:68:14 | n | $@ | main.rs:96:13:96:21 | source(...) | source(...) |
213+
| main.rs:68:14:68:14 | n | main.rs:109:13:109:21 | source(...) | main.rs:68:14:68:14 | n | $@ | main.rs:109:13:109:21 | source(...) | source(...) |
194214
| main.rs:91:10:91:10 | a | main.rs:75:13:75:21 | source(...) | main.rs:91:10:91:10 | a | $@ | main.rs:75:13:75:21 | source(...) | source(...) |
195215
| main.rs:104:10:104:10 | b | main.rs:102:13:102:21 | source(...) | main.rs:104:10:104:10 | b | $@ | main.rs:102:13:102:21 | source(...) | source(...) |
216+
| main.rs:117:10:117:10 | b | main.rs:115:13:115:22 | source(...) | main.rs:117:10:117:10 | b | $@ | main.rs:115:13:115:22 | source(...) | source(...) |
196217
| main.rs:136:10:136:10 | m | main.rs:134:24:134:33 | source(...) | main.rs:136:10:136:10 | m | $@ | main.rs:134:24:134:33 | source(...) | source(...) |
197218
| main.rs:188:10:188:10 | c | main.rs:185:28:185:36 | source(...) | main.rs:188:10:188:10 | c | $@ | main.rs:185:28:185:36 | source(...) | source(...) |
198219
| main.rs:193:10:193:10 | c | main.rs:191:28:191:37 | source(...) | main.rs:193:10:193:10 | c | $@ | main.rs:191:28:191:37 | source(...) | source(...) |

rust/ql/test/library-tests/dataflow/global/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ struct MyFlag {
6565

6666
impl MyFlag {
6767
fn data_in(&self, n: i64) {
68-
sink(n); // $ hasValueFlow=1 MISSING: hasValueFlow=8
68+
sink(n); // $ hasValueFlow=1 hasValueFlow=8
6969
}
7070

7171
fn get_data(&self) -> i64 {
@@ -114,7 +114,7 @@ fn data_through_method_called_as_function() {
114114
let mn = MyFlag { flag: true };
115115
let a = source(12);
116116
let b = MyFlag::data_through(&mn, a);
117-
sink(b); // $ MISSING: hasValueFlow=12
117+
sink(b); // $ hasValueFlow=12
118118
}
119119

120120
use std::ops::Add;

rust/ql/test/library-tests/path-resolution/main.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ mod m8 {
178178
pub fn g() {
179179
let x = MyStruct {}; // $ item=I50
180180
MyTrait::f(&x); // $ item=I48
181-
MyStruct::f(&x); // $ MISSING: item=I53
181+
MyStruct::f(&x); // $ item=I53
182182
<MyStruct as // $ item=I50
183183
MyTrait // $ MISSING: item=I47
184184
> // $ MISSING: item=52
@@ -187,7 +187,7 @@ mod m8 {
187187
x.f(); // $ MISSING: item=I53
188188
let x = MyStruct {}; // $ item=I50
189189
x.g(); // $ MISSING: item=I54
190-
MyStruct::h(&x); // $ MISSING: item=I74
190+
MyStruct::h(&x); // $ item=I74
191191
x.h(); // $ MISSING: item=I74
192192
} // I55
193193
} // I46
@@ -303,7 +303,7 @@ mod m15 {
303303
: Trait1 { // $ item=I79
304304
fn f(&self) {
305305
println!("m15::Trait2::f");
306-
Self::g(self); // $ MISSING: item=I80
306+
Self::g(self); // $ item=I80
307307
self.g(); // $ MISSING: item=I80
308308
}
309309
} // I82
@@ -342,7 +342,7 @@ mod m15 {
342342
<S // $ item=I81
343343
as Trait2 // MISSING: item=I82
344344
>::f(&x); // $ MISSING: item=I78
345-
S::g(&x); // $ MISSING: item=I77
345+
S::g(&x); // $ item=I77
346346
x.g(); // $ MISSING: item=I77
347347
} // I75
348348
}

rust/ql/test/library-tests/path-resolution/path-resolution.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,13 @@ resolvePath
9595
| main.rs:180:9:180:15 | MyTrait | main.rs:140:5:148:5 | trait MyTrait |
9696
| main.rs:180:9:180:18 | ...::f | main.rs:141:9:141:20 | fn f |
9797
| main.rs:181:9:181:16 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
98+
| main.rs:181:9:181:19 | ...::f | main.rs:157:33:162:9 | fn f |
9899
| main.rs:182:10:182:17 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
99100
| main.rs:182:10:182:17 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
100101
| main.rs:186:17:186:24 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
101102
| main.rs:188:17:188:24 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
102103
| main.rs:190:9:190:16 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
104+
| main.rs:190:9:190:19 | ...::h | main.rs:170:21:174:9 | fn h |
103105
| main.rs:199:19:199:22 | self | main.rs:195:1:203:1 | mod m9 |
104106
| main.rs:199:19:199:32 | ...::MyStruct | main.rs:196:5:196:26 | struct MyStruct |
105107
| main.rs:201:9:201:12 | self | main.rs:195:1:203:1 | mod m9 |
@@ -132,6 +134,7 @@ resolvePath
132134
| main.rs:289:13:289:13 | f | main.rs:280:5:280:17 | fn f |
133135
| main.rs:303:9:303:14 | Trait1 | main.rs:295:5:299:5 | trait Trait1 |
134136
| main.rs:306:13:306:16 | Self | main.rs:301:5:309:5 | trait Trait2 |
137+
| main.rs:306:13:306:19 | ...::g | main.rs:298:9:298:20 | fn g |
135138
| main.rs:314:10:314:15 | Trait1 | main.rs:295:5:299:5 | trait Trait1 |
136139
| main.rs:315:11:315:11 | S | main.rs:311:5:311:13 | struct S |
137140
| main.rs:318:13:318:16 | Self | main.rs:313:5:325:5 | impl Trait1 for S { ... } |
@@ -144,6 +147,7 @@ resolvePath
144147
| main.rs:342:10:342:10 | S | main.rs:311:5:311:13 | struct S |
145148
| main.rs:342:10:342:10 | S | main.rs:311:5:311:13 | struct S |
146149
| main.rs:345:9:345:9 | S | main.rs:311:5:311:13 | struct S |
150+
| main.rs:345:9:345:12 | ...::g | main.rs:322:9:324:9 | fn g |
147151
| main.rs:351:5:351:6 | my | main.rs:1:1:1:7 | mod my |
148152
| main.rs:351:5:351:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
149153
| main.rs:351:5:351:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |

0 commit comments

Comments
 (0)