Skip to content

Commit 94550bb

Browse files
committed
rust
1 parent 7d90774 commit 94550bb

File tree

7 files changed

+59
-30
lines changed

7 files changed

+59
-30
lines changed

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

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,57 @@ module Impl {
2929
result = getImmediateParent(e)
3030
}
3131

32+
cached
33+
private module MacroExpansion {
34+
pragma[nomagic]
35+
private predicate isInMacroExpansion(AstNode root, AstNode n) {
36+
n = root.(MacroCall).getMacroCallExpansion()
37+
or
38+
n = root.(Adt).getDeriveMacroExpansion(_)
39+
or
40+
n = root.(Item).getAttributeMacroExpansion()
41+
or
42+
isInMacroExpansion(root, n.getParentNode())
43+
}
44+
45+
pragma[nomagic]
46+
private predicate isInAttributeMacroExpansionSource(Item i, AstNode n) {
47+
i.hasAttributeMacroExpansion() and
48+
n.getParentNode() = i and
49+
not n = i.getAttributeMacroExpansion() and
50+
not n instanceof Attr
51+
or
52+
isInAttributeMacroExpansionSource(i, n.getParentNode())
53+
}
54+
55+
pragma[nomagic]
56+
private predicate isAttributeMacroExpansionSourceLocation(Item i, Location l) {
57+
exists(AstNode n |
58+
isInAttributeMacroExpansionSource(i, n) and
59+
n.getLocation() = l
60+
)
61+
}
62+
63+
/** Gets an AST node whose location is inside the token tree belonging to `mc`. */
64+
pragma[nomagic]
65+
private AstNode getATokenTreeNode(MacroCall mc) {
66+
isInMacroExpansion(mc, result) and
67+
mc.getTokenTree().getLocation().contains(result.getLocation())
68+
}
69+
70+
cached
71+
predicate isInMacroExpansion(AstNode n) { isInMacroExpansion(_, n) }
72+
73+
cached
74+
predicate isFromMacroExpansion(AstNode n) {
75+
exists(AstNode root |
76+
isInMacroExpansion(root, n) and
77+
not n = getATokenTreeNode(root) and
78+
not isAttributeMacroExpansionSourceLocation(root, n.getLocation())
79+
)
80+
}
81+
}
82+
3283
class AstNode extends Generated::AstNode {
3384
/**
3485
* Gets the nearest enclosing parent of this node, which is also an `AstNode`,
@@ -71,21 +122,15 @@ module Impl {
71122
}
72123

73124
/** Holds if this node is inside a macro expansion. */
74-
predicate isInMacroExpansion() { MacroCallImpl::isInMacroExpansion(_, this) }
125+
predicate isInMacroExpansion() { MacroExpansion::isInMacroExpansion(this) }
75126

76127
/**
77128
* Holds if this node exists only as the result of a macro expansion.
78129
*
79130
* This is the same as `isInMacroExpansion()`, but excludes AST nodes corresponding
80-
* to macro arguments.
131+
* to macro arguments, including attribute macro targets.
81132
*/
82-
pragma[nomagic]
83-
predicate isFromMacroExpansion() {
84-
exists(AstNode root |
85-
MacroCallImpl::isInMacroExpansion(root, this) and
86-
not this = root.(MacroCall).getATokenTreeNode()
87-
)
88-
}
133+
predicate isFromMacroExpansion() { MacroExpansion::isFromMacroExpansion(this) }
89134

90135
/**
91136
* Gets a control flow node for this AST node, if any.

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

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,6 @@ module Impl {
1414
private import rust
1515
private import codeql.rust.internal.PathResolution
1616

17-
pragma[nomagic]
18-
predicate isInMacroExpansion(AstNode root, AstNode n) {
19-
n = root.(MacroCall).getMacroCallExpansion()
20-
or
21-
n = root.(Adt).getDeriveMacroExpansion(_)
22-
or
23-
isInMacroExpansion(root, n.getParentNode())
24-
}
25-
2617
// the following QLdoc is generated: if you need to edit it, do it in the schema file
2718
/**
2819
* A macro invocation.
@@ -35,13 +26,6 @@ module Impl {
3526
class MacroCall extends Generated::MacroCall {
3627
override string toStringImpl() { result = this.getPath().toAbbreviatedString() + "!..." }
3728

38-
/** Gets an AST node whose location is inside the token tree belonging to this macro call. */
39-
pragma[nomagic]
40-
AstNode getATokenTreeNode() {
41-
isInMacroExpansion(this, result) and
42-
this.getTokenTree().getLocation().contains(result.getLocation())
43-
}
44-
4529
/**
4630
* Gets the macro definition that this macro call resolves to.
4731
*

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ private module ResolveTest implements TestSig {
1212

1313
private predicate itemAt(ItemNode i, string filepath, int line, boolean inMacro) {
1414
i.getLocation().hasLocationInfo(filepath, _, _, line, _) and
15-
if i.(AstNode).isInMacroExpansion() then inMacro = true else inMacro = false
15+
if i.(AstNode).isFromMacroExpansion() then inMacro = true else inMacro = false
1616
}
1717

1818
private predicate commmentAt(string text, string filepath, int line) {

rust/ql/src/queries/unusedentities/UnreachableCode.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ predicate hiddenNode(AstNode n) {
3333
n instanceof ControlFlowGraphImpl::PostOrderTree and // location is counter-intuitive
3434
not n instanceof MacroExpr
3535
or
36-
n.isInMacroExpansion()
36+
n.isFromMacroExpansion()
3737
}
3838

3939
/**

rust/ql/src/queries/unusedentities/UnusedValue.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ from AstNode write, Ssa::Variable v
1818
where
1919
variableWrite(_, write, v) and
2020
not v instanceof DiscardVariable and
21-
not write.isInMacroExpansion() and
21+
not write.isFromMacroExpansion() and
2222
not isAllowableUnused(v) and
2323
// SSA definitions are only created for live writes
2424
not write = any(Ssa::WriteDefinition def).getWriteAccess().getAstNode() and

rust/ql/src/queries/unusedentities/UnusedVariable.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class IncompleteCallable extends Callable {
3636
*/
3737
predicate isAllowableUnused(Variable v) {
3838
// in a macro expansion
39-
v.getPat().isInMacroExpansion()
39+
v.getPat().isFromMacroExpansion()
4040
or
4141
// declared in an incomplete callable
4242
v.getEnclosingCfgScope() instanceof IncompleteCallable

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ module VariableAccessTest implements TestSig {
3535
private predicate declAt(Variable v, string filepath, int line, boolean inMacro) {
3636
variable(v) and
3737
v.getLocation().hasLocationInfo(filepath, _, _, line, _) and
38-
if v.getPat().isInMacroExpansion() then inMacro = true else inMacro = false
38+
if v.getPat().isFromMacroExpansion() then inMacro = true else inMacro = false
3939
}
4040

4141
private predicate commmentAt(string text, string filepath, int line) {

0 commit comments

Comments
 (0)