Skip to content

Commit ea46030

Browse files
committed
Rust: Path resolution for static items
1 parent 4c31866 commit ea46030

17 files changed

Lines changed: 366 additions & 113 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* This module provides the public class `StaticAccess`.
3+
*/
4+
5+
private import internal.StaticImpl
6+
7+
final class StaticAccess = Impl::StaticAccess;

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ module Impl {
2424
* const X: i32 = 42;
2525
* ```
2626
*/
27-
class Const extends Generated::Const { }
27+
class Const extends Generated::Const {
28+
override string toStringImpl() { result = "const " + this.getName().getText() }
29+
}
2830

2931
/**
3032
* A constant access.

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

Lines changed: 26 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,38 @@ private class ConstItemNode extends AssocItemNode instanceof Const {
659659
override TypeParam getTypeParam(int i) { none() }
660660
}
661661

662+
private class StaticItemNode extends ItemNode instanceof Static {
663+
override string getName() { result = Static.super.getName().getText() }
664+
665+
override Namespace getNamespace() { result.isValue() }
666+
667+
override Visibility getVisibility() { result = Static.super.getVisibility() }
668+
669+
override Attr getAnAttr() { result = Static.super.getAnAttr() }
670+
671+
override TypeParam getTypeParam(int i) { none() }
672+
673+
override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) }
674+
675+
bindingset[c]
676+
private string getCanonicalPathPart(Crate c, int i) {
677+
i = 0 and
678+
result = this.getCanonicalPathPrefix(c)
679+
or
680+
i = 1 and
681+
result = "::"
682+
or
683+
i = 2 and
684+
result = this.getName()
685+
}
686+
687+
language[monotonicAggregates]
688+
override string getCanonicalPath(Crate c) {
689+
this.hasCanonicalPath(c) and
690+
result = strictconcat(int i | i in [0 .. 2] | this.getCanonicalPathPart(c, i) order by i)
691+
}
692+
}
693+
662694
private class TypeItemTypeItemNode extends NamedItemNode, TypeItemNode instanceof TypeItem {
663695
override string getName() { result = TypeItem.super.getName().getText() }
664696

rust/ql/lib/rust.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import codeql.rust.elements.AssignmentOperation
1111
import codeql.rust.elements.BitwiseOperation
1212
import codeql.rust.elements.ComparisonOperation
1313
import codeql.rust.elements.ConstAccess
14+
import codeql.rust.elements.StaticAccess
1415
import codeql.rust.elements.DerefExpr
1516
import codeql.rust.elements.LiteralExprExt
1617
import codeql.rust.elements.LogicalOperation

rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ private import utils.test.InlineExpectationsTest
1010
private module ResolveTest implements TestSig {
1111
string getARelevantTag() { result = ["item", "target", "item_not_target"] }
1212

13-
private predicate itemAt(ItemNode i, string filepath, int line) {
14-
i.getLocation().hasLocationInfo(filepath, _, _, line, _)
15-
}
16-
1713
private predicate commmentAt(string text, string filepath, int line) {
1814
exists(Comment c |
1915
c.getLocation().hasLocationInfo(filepath, line, _, _, _) and
@@ -23,6 +19,10 @@ private module ResolveTest implements TestSig {
2319
)
2420
}
2521

22+
private predicate itemAt(ItemNode i, string filepath, int line) {
23+
i.getLocation().hasLocationInfo(filepath, _, _, line, _)
24+
}
25+
2626
private predicate item(ItemNode i, string value) {
2727
exists(string filepath, int line | itemAt(i, filepath, line) |
2828
if i instanceof SourceFile

rust/ql/test/TestUtils.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,12 @@ class CrateElement extends Element {
2020
class Builtin extends AstNode {
2121
Builtin() { this.getFile().getAbsolutePath().matches("%/builtins/%.rs") }
2222
}
23+
24+
predicate commmentAt(string text, string filepath, int line) {
25+
exists(Comment c |
26+
c.getLocation().hasLocationInfo(filepath, line, _, _, _) and
27+
c.getCommentText().trim() = text and
28+
c.fromSource() and
29+
not text.matches("$%")
30+
)
31+
}
Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
testFailures
22
constAccess
3-
| main.rs:17:13:17:24 | GLOBAL_CONST | main.rs:1:1:1:29 | Const |
4-
| main.rs:19:13:19:24 | STRING_CONST | main.rs:2:1:2:35 | Const |
5-
| main.rs:21:13:21:33 | ...::ASSOC_CONST | main.rs:9:5:9:33 | Const |
6-
| main.rs:23:13:23:35 | ...::MODULE_CONST | main.rs:13:5:13:38 | Const |
7-
| main.rs:25:8:25:19 | GLOBAL_CONST | main.rs:1:1:1:29 | Const |
8-
| main.rs:29:16:29:36 | ...::ASSOC_CONST | main.rs:9:5:9:33 | Const |
3+
| main.rs:17:13:17:24 | GLOBAL_CONST | main.rs:1:1:1:29 | const GLOBAL_CONST |
4+
| main.rs:19:13:19:24 | STRING_CONST | main.rs:2:1:2:35 | const STRING_CONST |
5+
| main.rs:21:13:21:33 | ...::ASSOC_CONST | main.rs:9:5:9:33 | const ASSOC_CONST |
6+
| main.rs:23:13:23:35 | ...::MODULE_CONST | main.rs:13:5:13:38 | const MODULE_CONST |
7+
| main.rs:26:16:26:27 | GLOBAL_CONST | main.rs:1:1:1:29 | const GLOBAL_CONST |
8+
| main.rs:30:16:30:36 | ...::ASSOC_CONST | main.rs:9:5:9:33 | const ASSOC_CONST |
9+
| main.rs:33:20:33:31 | GLOBAL_CONST | main.rs:1:1:1:29 | const GLOBAL_CONST |
10+
| main.rs:39:17:39:28 | STRING_CONST | main.rs:38:9:38:43 | const STRING_CONST |
11+
| main.rs:43:21:43:32 | STRING_CONST | main.rs:42:13:42:48 | const STRING_CONST |

rust/ql/test/library-tests/const_access/const_access.ql

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,25 @@ import TestUtils
55
query predicate constAccess(ConstAccess ca, Const c) { toBeTested(ca) and c = ca.getConst() }
66

77
module ConstAccessTest implements TestSig {
8+
private predicate constAt(Const c, string filepath, int line) {
9+
c.getLocation().hasLocationInfo(filepath, _, _, line, _)
10+
}
11+
812
string getARelevantTag() { result = "const_access" }
913

1014
predicate hasActualResult(Location location, string element, string tag, string value) {
11-
exists(ConstAccess ca |
15+
exists(ConstAccess ca, Const c, string filepath, int line |
1216
toBeTested(ca) and
1317
location = ca.getLocation() and
1418
element = ca.toString() and
1519
tag = "const_access" and
16-
value = ca.getConst().getName().getText()
20+
c = ca.getConst() and
21+
constAt(c, filepath, line)
22+
|
23+
commmentAt(value, filepath, line)
24+
or
25+
not commmentAt(_, filepath, line) and
26+
value = c.getName().getText()
1727
)
1828
}
1929
}

rust/ql/test/library-tests/const_access/main.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,34 @@ mod my_module {
1515

1616
fn use_consts() {
1717
let x = GLOBAL_CONST; // $ const_access=GLOBAL_CONST
18-
18+
1919
let s = STRING_CONST; // $ const_access=STRING_CONST
20-
20+
2121
let y = MyStruct::ASSOC_CONST; // $ const_access=ASSOC_CONST
22-
22+
2323
let z = my_module::MODULE_CONST; // $ const_access=MODULE_CONST
24-
25-
if GLOBAL_CONST > 0 { // $ const_access=GLOBAL_CONST
24+
25+
#[rustfmt::skip]
26+
let _ = if GLOBAL_CONST > 0 { // $ const_access=GLOBAL_CONST
2627
println!("positive");
27-
}
28-
28+
};
29+
2930
let arr = [MyStruct::ASSOC_CONST; 5]; // $ const_access=ASSOC_CONST
31+
32+
#[rustfmt::skip]
33+
let _ = if let GLOBAL_CONST = 0 { // $ const_access=GLOBAL_CONST
34+
println!("zero");
35+
};
36+
37+
{
38+
const STRING_CONST: &str = "inner"; // Inner1
39+
let _ = STRING_CONST; // $ const_access=Inner1
40+
41+
{
42+
const STRING_CONST: &str = "inner2"; // Inner2
43+
let _ = STRING_CONST; // $ const_access=Inner2
44+
}
45+
}
3046
}
3147

3248
fn main() {

0 commit comments

Comments
 (0)