Rust: fixes

This commit is contained in:
Arthur Baars
2025-05-19 21:30:39 +02:00
committed by Tom Hvitved
parent 456a4b2be8
commit 44a404571f
10 changed files with 545 additions and 41 deletions

View File

@@ -34,8 +34,9 @@ impl Translator<'_> {
{{#nodes}}
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
{{#has_attrs}}
if self.should_be_excluded(node) { return None; }
{{#has_attrs}}
if self.should_be_excluded_attrs(node) { return None; }
{{/has_attrs}}
{{#fields}}
{{#predicate}}

View File

@@ -1,4 +1,5 @@
use crate::config::Config;
use crate::translate::SourceKind;
use anyhow::Context;
use chrono::{DateTime, Utc};
use ra_ap_project_model::ProjectManifest;
@@ -83,6 +84,8 @@ pub enum ExtractionStepKind {
LoadSource,
Parse,
Extract,
ParseLibrary,
ExtractLibrary,
CrateGraph,
}
@@ -113,18 +116,24 @@ impl ExtractionStep {
)
}
pub fn parse(start: Instant, target: &Path) -> Self {
pub fn parse(start: Instant, source_kind: SourceKind, target: &Path) -> Self {
Self::new(
start,
ExtractionStepKind::Parse,
match source_kind {
SourceKind::Source => ExtractionStepKind::Parse,
SourceKind::Library => ExtractionStepKind::ParseLibrary,
},
Some(PathBuf::from(target)),
)
}
pub fn extract(start: Instant, target: &Path) -> Self {
pub fn extract(start: Instant, source_kind: SourceKind, target: &Path) -> Self {
Self::new(
start,
ExtractionStepKind::Extract,
match source_kind {
SourceKind::Source => ExtractionStepKind::Extract,
SourceKind::Library => ExtractionStepKind::ExtractLibrary,
},
Some(PathBuf::from(target)),
)
}

View File

@@ -63,7 +63,8 @@ impl<'a> Extractor<'a> {
errors,
semantics_info,
} = rust_analyzer.parse(file);
self.steps.push(ExtractionStep::parse(before_parse, file));
self.steps
.push(ExtractionStep::parse(before_parse, source_kind, file));
let before_extract = Instant::now();
let line_index = LineIndex::new(text.as_ref());
@@ -108,7 +109,7 @@ impl<'a> Extractor<'a> {
)
});
self.steps
.push(ExtractionStep::extract(before_extract, file));
.push(ExtractionStep::extract(before_extract, source_kind, file));
}
pub fn extract_with_semantics(

View File

@@ -93,7 +93,7 @@ pub enum ResolvePaths {
Yes,
No,
}
#[derive(PartialEq, Eq)]
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum SourceKind {
Source,
Library,
@@ -619,7 +619,17 @@ impl<'a> Translator<'a> {
})();
}
pub(crate) fn should_be_excluded(&self, item: &impl ast::HasAttrs) -> bool {
pub(crate) fn should_be_excluded_attrs(&self, item: &impl ast::HasAttrs) -> bool {
self.semantics.is_some_and(|sema| {
item.attrs().any(|attr| {
attr.as_simple_call().is_some_and(|(name, tokens)| {
name == "cfg" && sema.check_cfg_attr(&tokens) == Some(false)
})
})
})
}
pub(crate) fn should_be_excluded(&self, item: &impl ast::AstNode) -> bool {
if self.source_kind == SourceKind::Library {
let syntax = item.syntax();
if let Some(body) = syntax.parent().and_then(Fn::cast).and_then(|x| x.body()) {
@@ -645,13 +655,7 @@ impl<'a> Translator<'a> {
}
}
}
self.semantics.is_some_and(|sema| {
item.attrs().any(|attr| {
attr.as_simple_call().is_some_and(|(name, tokens)| {
name == "cfg" && sema.check_cfg_attr(&tokens) == Some(false)
})
})
})
return false;
}
pub(crate) fn extract_types_from_path_segment(

File diff suppressed because it is too large Load Diff

View File

@@ -5,13 +5,16 @@
*/
import rust
import codeql.rust.internal.PathResolution
predicate nodes(Item i) { i instanceof RelevantNode }
class RelevantNode extends Item {
class RelevantNode extends Element instanceof ItemNode {
RelevantNode() {
this.getParentNode*() =
any(Crate m | m.getName() = "test" and m.getVersion() = "0.0.1").getModule()
this.(ItemNode).getImmediateParentModule*() =
any(Crate m | m.getName() = "test" and m.getVersion() = "0.0.1")
.(CrateItemNode)
.getModuleNode()
}
string label() { result = this.toString() }
@@ -26,9 +29,8 @@ class HasGenericParams extends RelevantNode {
params = this.(Struct).getGenericParamList() or
params = this.(Union).getGenericParamList() or
params = this.(Impl).getGenericParamList() or
params = this.(Enum).getGenericParamList() or
params = this.(Trait).getGenericParamList() or
params = this.(TraitAlias).getGenericParamList()
params = this.(Trait).getGenericParamList() // or
//params = this.(TraitAlias).getGenericParamList()
}
override string label() {

View File

@@ -1,23 +1,28 @@
import rust
import codeql.rust.controlflow.ControlFlowGraph
import codeql.rust.controlflow.BasicBlocks
import TestUtils
query predicate dominates(BasicBlock bb1, BasicBlock bb2) { bb1.dominates(bb2) }
query predicate dominates(BasicBlock bb1, BasicBlock bb2) {
toBeTested(bb1.getScope()) and bb1.dominates(bb2)
}
query predicate postDominance(BasicBlock bb1, BasicBlock bb2) { bb1.postDominates(bb2) }
query predicate postDominance(BasicBlock bb1, BasicBlock bb2) {
toBeTested(bb1.getScope()) and bb1.postDominates(bb2)
}
query predicate immediateDominator(BasicBlock bb1, BasicBlock bb2) {
bb1.getImmediateDominator() = bb2
toBeTested(bb1.getScope()) and bb1.getImmediateDominator() = bb2
}
query predicate controls(ConditionBasicBlock bb1, BasicBlock bb2, SuccessorType t) {
bb1.edgeDominates(bb2, t)
toBeTested(bb1.getScope()) and bb1.edgeDominates(bb2, t)
}
query predicate successor(ConditionBasicBlock bb1, BasicBlock bb2, SuccessorType t) {
bb1.getASuccessor(t) = bb2
toBeTested(bb1.getScope()) and bb1.getASuccessor(t) = bb2
}
query predicate joinBlockPredecessor(JoinBasicBlock bb1, BasicBlock bb2, int i) {
bb1.getJoinBlockPredecessor(i) = bb2
toBeTested(bb1.getScope()) and bb1.getJoinBlockPredecessor(i) = bb2
}

View File

@@ -1,5 +1,6 @@
import rust
import utils.test.InlineExpectationsTest
import TestUtils
string describe(Expr op) {
op instanceof Operation and result = "Operation"
@@ -20,6 +21,7 @@ module OperationsTest implements TestSig {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Expr op |
toBeTested(op) and
location = op.getLocation() and
location.getFile().getBaseName() != "" and
element = op.toString() and

View File

@@ -4,31 +4,38 @@ import codeql.rust.controlflow.ControlFlowGraph
import codeql.rust.dataflow.Ssa
import codeql.rust.dataflow.internal.SsaImpl
import Impl::TestAdjacentRefs as RefTest
import TestUtils
query predicate definition(Ssa::Definition def, Variable v) { def.getSourceVariable() = v }
query predicate definition(Ssa::Definition def, Variable v) {
toBeTested(v.getEnclosingCfgScope()) and def.getSourceVariable() = v
}
query predicate read(Ssa::Definition def, Variable v, CfgNode read) {
def.getSourceVariable() = v and read = def.getARead()
toBeTested(v.getEnclosingCfgScope()) and def.getSourceVariable() = v and read = def.getARead()
}
query predicate firstRead(Ssa::Definition def, Variable v, CfgNode read) {
def.getSourceVariable() = v and read = def.getAFirstRead()
toBeTested(v.getEnclosingCfgScope()) and
def.getSourceVariable() = v and
read = def.getAFirstRead()
}
query predicate adjacentReads(Ssa::Definition def, Variable v, CfgNode read1, CfgNode read2) {
toBeTested(v.getEnclosingCfgScope()) and
def.getSourceVariable() = v and
def.hasAdjacentReads(read1, read2)
}
query predicate phi(Ssa::PhiDefinition phi, Variable v, Ssa::Definition input) {
phi.getSourceVariable() = v and input = phi.getAnInput()
toBeTested(v.getEnclosingCfgScope()) and phi.getSourceVariable() = v and input = phi.getAnInput()
}
query predicate phiReadNode(RefTest::Ref phi, Variable v) {
phi.isPhiRead() and phi.getSourceVariable() = v
toBeTested(v.getEnclosingCfgScope()) and phi.isPhiRead() and phi.getSourceVariable() = v
}
query predicate phiReadNodeFirstRead(RefTest::Ref phi, Variable v, CfgNode read) {
toBeTested(v.getEnclosingCfgScope()) and
exists(RefTest::Ref r, BasicBlock bb, int i |
phi.isPhiRead() and
RefTest::adjacentRefRead(phi, r) and

View File

@@ -1,29 +1,39 @@
import rust
import utils.test.InlineExpectationsTest
import codeql.rust.elements.internal.VariableImpl::Impl as VariableImpl
import TestUtils
query predicate variable(Variable v) { any() }
query predicate variable(Variable v) { toBeTested(v.getEnclosingCfgScope()) }
query predicate variableAccess(VariableAccess va, Variable v) { v = va.getVariable() }
query predicate variableAccess(VariableAccess va, Variable v) {
variable(v) and toBeTested(va) and v = va.getVariable()
}
query predicate variableWriteAccess(VariableWriteAccess va, Variable v) { v = va.getVariable() }
query predicate variableWriteAccess(VariableWriteAccess va, Variable v) {
variable(v) and toBeTested(va) and v = va.getVariable()
}
query predicate variableReadAccess(VariableReadAccess va, Variable v) { v = va.getVariable() }
query predicate variableReadAccess(VariableReadAccess va, Variable v) {
variable(v) and toBeTested(va) and v = va.getVariable()
}
query predicate variableInitializer(Variable v, Expr e) { e = v.getInitializer() }
query predicate variableInitializer(Variable v, Expr e) {
variable(v) and toBeTested(e) and e = v.getInitializer()
}
query predicate capturedVariable(Variable v) { v.isCaptured() }
query predicate capturedVariable(Variable v) { variable(v) and v.isCaptured() }
query predicate capturedAccess(VariableAccess va) { va.isCapture() }
query predicate capturedAccess(VariableAccess va) { toBeTested(va) and va.isCapture() }
query predicate nestedFunctionAccess(VariableImpl::NestedFunctionAccess nfa, Function f) {
f = nfa.getFunction()
toBeTested(f) and f = nfa.getFunction()
}
module VariableAccessTest implements TestSig {
string getARelevantTag() { result = ["", "write_", "read_"] + "access" }
private predicate declAt(Variable v, string filepath, int line, boolean inMacro) {
variable(v) and
v.getLocation().hasLocationInfo(filepath, _, _, line, _) and
if v.getPat().isInMacroExpansion() then inMacro = true else inMacro = false
}
@@ -46,6 +56,7 @@ module VariableAccessTest implements TestSig {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(VariableAccess va |
toBeTested(va) and
location = va.getLocation() and
element = va.toString() and
decl(va.getVariable(), value)