mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Rust: fixes
This commit is contained in:
committed by
Tom Hvitved
parent
456a4b2be8
commit
44a404571f
@@ -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}}
|
||||
|
||||
@@ -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)),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
462
rust/extractor/src/translate/generated.rs
generated
462
rust/extractor/src/translate/generated.rs
generated
File diff suppressed because it is too large
Load Diff
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user