mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge branch 'main' into unusedvar8
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
use crate::rust_analyzer::path_to_file_id;
|
||||
use anyhow::Context;
|
||||
use archive::Archiver;
|
||||
use log::info;
|
||||
use ra_ap_hir::Semantics;
|
||||
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
|
||||
use ra_ap_ide_db::RootDatabase;
|
||||
use ra_ap_project_model::ProjectManifest;
|
||||
use ra_ap_vfs::Vfs;
|
||||
use rust_analyzer::{ParseResult, RustAnalyzer};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
mod archive;
|
||||
mod config;
|
||||
pub mod generated;
|
||||
@@ -17,54 +21,71 @@ mod rust_analyzer;
|
||||
mod translate;
|
||||
pub mod trap;
|
||||
|
||||
fn extract(
|
||||
rust_analyzer: &rust_analyzer::RustAnalyzer,
|
||||
archiver: &Archiver,
|
||||
traps: &trap::TrapFileProvider,
|
||||
file: &std::path::Path,
|
||||
) {
|
||||
archiver.archive(file);
|
||||
struct Extractor<'a> {
|
||||
archiver: &'a Archiver,
|
||||
traps: &'a trap::TrapFileProvider,
|
||||
}
|
||||
|
||||
let ParseResult {
|
||||
ast,
|
||||
text,
|
||||
errors,
|
||||
file_id,
|
||||
} = rust_analyzer.parse(file);
|
||||
let line_index = LineIndex::new(text.as_ref());
|
||||
let display_path = file.to_string_lossy();
|
||||
let mut trap = traps.create("source", file);
|
||||
let label = trap.emit_file(file);
|
||||
let mut translator = translate::Translator::new(
|
||||
trap,
|
||||
display_path.as_ref(),
|
||||
label,
|
||||
line_index,
|
||||
file_id,
|
||||
file_id.and(rust_analyzer.semantics()),
|
||||
);
|
||||
impl Extractor<'_> {
|
||||
fn extract(&self, rust_analyzer: &rust_analyzer::RustAnalyzer, file: &std::path::Path) {
|
||||
self.archiver.archive(file);
|
||||
|
||||
for err in errors {
|
||||
translator.emit_parse_error(&ast, &err);
|
||||
}
|
||||
let no_location = (LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
|
||||
if translator.semantics.is_none() {
|
||||
translator.emit_diagnostic(
|
||||
trap::DiagnosticSeverity::Warning,
|
||||
"semantics".to_owned(),
|
||||
"semantic analyzer unavailable".to_owned(),
|
||||
"semantic analyzer unavailable: macro expansion, call graph, and type inference will be skipped.".to_owned(),
|
||||
no_location,
|
||||
let ParseResult {
|
||||
ast,
|
||||
text,
|
||||
errors,
|
||||
semantics_info,
|
||||
} = rust_analyzer.parse(file);
|
||||
let line_index = LineIndex::new(text.as_ref());
|
||||
let display_path = file.to_string_lossy();
|
||||
let mut trap = self.traps.create("source", file);
|
||||
let label = trap.emit_file(file);
|
||||
let mut translator = translate::Translator::new(
|
||||
trap,
|
||||
display_path.as_ref(),
|
||||
label,
|
||||
line_index,
|
||||
semantics_info.as_ref().ok(),
|
||||
);
|
||||
|
||||
for err in errors {
|
||||
translator.emit_parse_error(&ast, &err);
|
||||
}
|
||||
let no_location = (LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
|
||||
if let Err(reason) = semantics_info {
|
||||
let message = format!("semantic analyzer unavailable ({reason})");
|
||||
let full_message = format!(
|
||||
"{message}: macro expansion, call graph, and type inference will be skipped."
|
||||
);
|
||||
translator.emit_diagnostic(
|
||||
trap::DiagnosticSeverity::Warning,
|
||||
"semantics".to_owned(),
|
||||
message,
|
||||
full_message,
|
||||
no_location,
|
||||
);
|
||||
}
|
||||
translator.emit_source_file(ast);
|
||||
translator.trap.commit().unwrap_or_else(|err| {
|
||||
log::error!(
|
||||
"Failed to write trap file for: {}: {}",
|
||||
display_path,
|
||||
err.to_string()
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
pub fn extract_with_semantics(
|
||||
&self,
|
||||
file: &Path,
|
||||
semantics: &Semantics<'_, RootDatabase>,
|
||||
vfs: &Vfs,
|
||||
) {
|
||||
self.extract(&RustAnalyzer::new(vfs, semantics), file);
|
||||
}
|
||||
pub fn extract_without_semantics(&self, file: &Path, reason: &str) {
|
||||
self.extract(&RustAnalyzer::WithoutSemantics { reason }, file);
|
||||
}
|
||||
translator.emit_source_file(ast);
|
||||
translator.trap.commit().unwrap_or_else(|err| {
|
||||
log::error!(
|
||||
"Failed to write trap file for: {}: {}",
|
||||
display_path,
|
||||
err.to_string()
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
@@ -82,6 +103,10 @@ fn main() -> anyhow::Result<()> {
|
||||
let archiver = archive::Archiver {
|
||||
root: cfg.source_archive_dir.clone(),
|
||||
};
|
||||
let extractor = Extractor {
|
||||
archiver: &archiver,
|
||||
traps: &traps,
|
||||
};
|
||||
let files: Vec<PathBuf> = cfg
|
||||
.inputs
|
||||
.iter()
|
||||
@@ -95,38 +120,39 @@ fn main() -> anyhow::Result<()> {
|
||||
.iter()
|
||||
.map(|x| (x.manifest_path().parent().as_ref(), (x, Vec::new())))
|
||||
.collect();
|
||||
let mut other_files = Vec::new();
|
||||
|
||||
'outer: for file in &files {
|
||||
let mut p = file.as_path();
|
||||
while let Some(parent) = p.parent() {
|
||||
p = parent;
|
||||
if let Some((_, files)) = map.get_mut(parent) {
|
||||
for ancestor in file.as_path().ancestors() {
|
||||
if let Some((_, files)) = map.get_mut(ancestor) {
|
||||
files.push(file);
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
other_files.push(file);
|
||||
extractor.extract_without_semantics(file, "no manifest found");
|
||||
}
|
||||
for (manifest, files) in map.values() {
|
||||
if files.is_empty() {
|
||||
break;
|
||||
}
|
||||
for (manifest, files) in map.values().filter(|(_, files)| !files.is_empty()) {
|
||||
if let Some((ref db, ref vfs)) = RustAnalyzer::load_workspace(manifest, &cfg.scratch_dir) {
|
||||
let semantics = Semantics::new(db);
|
||||
let rust_analyzer = RustAnalyzer::new(vfs, semantics);
|
||||
for file in files {
|
||||
extract(&rust_analyzer, &archiver, &traps, file);
|
||||
let Some(id) = path_to_file_id(file, vfs) else {
|
||||
extractor.extract_without_semantics(
|
||||
file,
|
||||
"not included in files loaded from manifest",
|
||||
);
|
||||
continue;
|
||||
};
|
||||
if semantics.file_to_module_def(id).is_none() {
|
||||
extractor.extract_without_semantics(file, "not included as a module");
|
||||
continue;
|
||||
}
|
||||
extractor.extract_with_semantics(file, &semantics, vfs);
|
||||
}
|
||||
} else {
|
||||
for file in files {
|
||||
extract(&RustAnalyzer::WithoutSemantics, &archiver, &traps, file);
|
||||
extractor.extract_without_semantics(file, "unable to load manifest");
|
||||
}
|
||||
}
|
||||
}
|
||||
for file in other_files {
|
||||
extract(&RustAnalyzer::WithoutSemantics, &archiver, &traps, file);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -14,25 +14,34 @@ use ra_ap_span::TextRange;
|
||||
use ra_ap_span::TextSize;
|
||||
use ra_ap_syntax::SourceFile;
|
||||
use ra_ap_syntax::SyntaxError;
|
||||
use ra_ap_vfs::AbsPathBuf;
|
||||
use ra_ap_vfs::Vfs;
|
||||
use ra_ap_vfs::VfsPath;
|
||||
use ra_ap_vfs::{AbsPathBuf, FileId};
|
||||
use std::borrow::Cow;
|
||||
use std::path::{Path, PathBuf};
|
||||
use triomphe::Arc;
|
||||
pub enum RustAnalyzer<'a> {
|
||||
WithSemantics {
|
||||
vfs: &'a Vfs,
|
||||
semantics: Semantics<'a, RootDatabase>,
|
||||
semantics: &'a Semantics<'a, RootDatabase>,
|
||||
},
|
||||
WithoutSemantics {
|
||||
reason: &'a str,
|
||||
},
|
||||
WithoutSemantics,
|
||||
}
|
||||
pub struct ParseResult {
|
||||
|
||||
pub struct FileSemanticInformation<'a> {
|
||||
pub file_id: EditionedFileId,
|
||||
pub semantics: &'a Semantics<'a, RootDatabase>,
|
||||
}
|
||||
|
||||
pub struct ParseResult<'a> {
|
||||
pub ast: SourceFile,
|
||||
pub text: Arc<str>,
|
||||
pub errors: Vec<SyntaxError>,
|
||||
pub file_id: Option<EditionedFileId>,
|
||||
pub semantics_info: Result<FileSemanticInformation<'a>, &'a str>,
|
||||
}
|
||||
|
||||
impl<'a> RustAnalyzer<'a> {
|
||||
pub fn load_workspace(
|
||||
project: &ProjectManifest,
|
||||
@@ -61,47 +70,45 @@ impl<'a> RustAnalyzer<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn new(vfs: &'a Vfs, semantics: Semantics<'a, RootDatabase>) -> Self {
|
||||
pub fn new(vfs: &'a Vfs, semantics: &'a Semantics<'a, RootDatabase>) -> Self {
|
||||
RustAnalyzer::WithSemantics { vfs, semantics }
|
||||
}
|
||||
pub fn semantics(&'a self) -> Option<&'a Semantics<'a, RootDatabase>> {
|
||||
match self {
|
||||
RustAnalyzer::WithSemantics { vfs: _, semantics } => Some(semantics),
|
||||
RustAnalyzer::WithoutSemantics => None,
|
||||
}
|
||||
}
|
||||
pub fn parse(&self, path: &Path) -> ParseResult {
|
||||
if let RustAnalyzer::WithSemantics { vfs, semantics } = self {
|
||||
if let Some(file_id) = Utf8PathBuf::from_path_buf(path.to_path_buf())
|
||||
.ok()
|
||||
.and_then(|x| AbsPathBuf::try_from(x).ok())
|
||||
.map(VfsPath::from)
|
||||
.and_then(|x| vfs.file_id(&x))
|
||||
{
|
||||
if let Ok(input) = std::panic::catch_unwind(|| semantics.db.file_text(file_id)) {
|
||||
let file_id = EditionedFileId::current_edition(file_id);
|
||||
let source_file = semantics.parse(file_id);
|
||||
let errors = semantics
|
||||
.db
|
||||
.parse_errors(file_id)
|
||||
.into_iter()
|
||||
.flat_map(|x| x.to_vec())
|
||||
.collect();
|
||||
let no_semantics_reason;
|
||||
match self {
|
||||
RustAnalyzer::WithSemantics { vfs, semantics } => {
|
||||
if let Some(file_id) = path_to_file_id(path, vfs) {
|
||||
if let Ok(input) = std::panic::catch_unwind(|| semantics.db.file_text(file_id))
|
||||
{
|
||||
let file_id = EditionedFileId::current_edition(file_id);
|
||||
let source_file = semantics.parse(file_id);
|
||||
let errors = semantics
|
||||
.db
|
||||
.parse_errors(file_id)
|
||||
.into_iter()
|
||||
.flat_map(|x| x.to_vec())
|
||||
.collect();
|
||||
|
||||
return ParseResult {
|
||||
ast: source_file,
|
||||
text: input,
|
||||
errors,
|
||||
file_id: Some(file_id),
|
||||
};
|
||||
} else {
|
||||
log::debug!(
|
||||
return ParseResult {
|
||||
ast: source_file,
|
||||
text: input,
|
||||
errors,
|
||||
semantics_info: Ok(FileSemanticInformation { file_id, semantics }),
|
||||
};
|
||||
}
|
||||
debug!(
|
||||
"No text available for file_id '{:?}', falling back to loading file '{}' from disk.",
|
||||
file_id,
|
||||
path.to_string_lossy()
|
||||
)
|
||||
);
|
||||
no_semantics_reason = "no text available for the file in the project";
|
||||
} else {
|
||||
no_semantics_reason = "file not found in project";
|
||||
}
|
||||
}
|
||||
RustAnalyzer::WithoutSemantics { reason } => {
|
||||
no_semantics_reason = reason;
|
||||
}
|
||||
}
|
||||
let mut errors = Vec::new();
|
||||
let input = match std::fs::read(path) {
|
||||
@@ -123,7 +130,7 @@ impl<'a> RustAnalyzer<'a> {
|
||||
ast: parse.tree(),
|
||||
text: input.as_ref().into(),
|
||||
errors,
|
||||
file_id: None,
|
||||
semantics_info: Err(no_semantics_reason),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,3 +194,11 @@ fn from_utf8_lossy(v: &[u8]) -> (Cow<'_, str>, Option<SyntaxError>) {
|
||||
|
||||
(Cow::Owned(res), Some(error))
|
||||
}
|
||||
|
||||
pub(crate) fn path_to_file_id(path: &Path, vfs: &Vfs) -> Option<FileId> {
|
||||
Utf8PathBuf::from_path_buf(path.to_path_buf())
|
||||
.ok()
|
||||
.and_then(|x| AbsPathBuf::try_from(x).ok())
|
||||
.map(VfsPath::from)
|
||||
.and_then(|x| vfs.file_id(&x))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::mappings::{AddressableAst, AddressableHir};
|
||||
use crate::generated::MacroCall;
|
||||
use crate::generated::{self};
|
||||
use crate::rust_analyzer::FileSemanticInformation;
|
||||
use crate::trap::{DiagnosticSeverity, TrapFile, TrapId};
|
||||
use crate::trap::{Label, TrapClass};
|
||||
use codeql_extractor::trap::{self};
|
||||
@@ -64,16 +65,15 @@ impl<'a> Translator<'a> {
|
||||
path: &'a str,
|
||||
label: trap::Label,
|
||||
line_index: LineIndex,
|
||||
file_id: Option<EditionedFileId>,
|
||||
semantics: Option<&'a Semantics<'a, RootDatabase>>,
|
||||
semantic_info: Option<&FileSemanticInformation<'a>>,
|
||||
) -> Translator<'a> {
|
||||
Translator {
|
||||
trap,
|
||||
path,
|
||||
label,
|
||||
line_index,
|
||||
file_id,
|
||||
semantics,
|
||||
file_id: semantic_info.map(|i| i.file_id),
|
||||
semantics: semantic_info.map(|i| i.semantics),
|
||||
}
|
||||
}
|
||||
fn location(&self, range: TextRange) -> (LineCol, LineCol) {
|
||||
@@ -160,7 +160,7 @@ impl<'a> Translator<'a> {
|
||||
self.path,
|
||||
start.line + 1,
|
||||
start.col + 1,
|
||||
&message
|
||||
&full_message
|
||||
);
|
||||
if severity > DiagnosticSeverity::Debug {
|
||||
let location = self.trap.emit_location_label(self.label, start, end);
|
||||
@@ -284,7 +284,8 @@ impl<'a> Translator<'a> {
|
||||
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
} else if self.semantics.is_some() {
|
||||
// let's not spam warnings if we don't have semantics, we already emitted one
|
||||
let range = self.text_range_for_node(mcall);
|
||||
self.emit_parse_error(
|
||||
mcall,
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* @name Data flow inconsistencies
|
||||
* @description Lists the data flow inconsistencies in the database. This query is intended for internal use.
|
||||
* @kind table
|
||||
* @id rust/diagnostics/data-flow-consistency
|
||||
*/
|
||||
|
||||
import codeql.rust.dataflow.DataFlow::DataFlow as DataFlow
|
||||
private import rust
|
||||
private import codeql.rust.dataflow.internal.DataFlowImpl
|
||||
|
||||
30
rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll
Normal file
30
rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Provides subclasses of `CfgNode` that represents different types of nodes in
|
||||
* the control flow graph.
|
||||
*/
|
||||
|
||||
private import rust
|
||||
private import ControlFlowGraph
|
||||
private import internal.ControlFlowGraphImpl
|
||||
|
||||
/** A CFG node that corresponds to an element in the AST. */
|
||||
class AstCfgNode extends CfgNode {
|
||||
AstNode node;
|
||||
|
||||
AstCfgNode() { node = this.getAstNode() }
|
||||
}
|
||||
|
||||
/** A CFG node that corresponds to an expression in the AST. */
|
||||
class ExprCfgNode extends AstCfgNode {
|
||||
override Expr node;
|
||||
|
||||
/** Gets the underlying expression. */
|
||||
Expr getExpr() { result = node }
|
||||
}
|
||||
|
||||
/** A CFG node that corresponds to a call in the AST. */
|
||||
class CallCfgNode extends ExprCfgNode {
|
||||
override CallExpr node;
|
||||
}
|
||||
|
||||
final class ExitCfgNode = ExitNode;
|
||||
@@ -611,7 +611,7 @@ module ExprTrees {
|
||||
* Provides `ControlFlowTree`s for patterns.
|
||||
*
|
||||
* Since patterns destruct values, they are modeled in pre-order, except for
|
||||
* `OrPat`s and `IdentPat`s.
|
||||
* `LiteralPat`s, `OrPat`s, and `IdentPat`s.
|
||||
*/
|
||||
module PatternTrees {
|
||||
abstract class StandardPatTree extends StandardTree {
|
||||
@@ -665,7 +665,9 @@ module PatternTrees {
|
||||
|
||||
class RestPatTree extends LeafTree, RestPat { }
|
||||
|
||||
class LiteralPatTree extends LeafTree, LiteralPat { }
|
||||
class LiteralPatTree extends StandardPostOrderTree, LiteralPat {
|
||||
override AstNode getChildNode(int i) { i = 0 and result = this.getLiteral() }
|
||||
}
|
||||
|
||||
class MacroPatTree extends PreOrderPatTree, MacroPat {
|
||||
override Pat getPat(int i) { i = 0 and result = this.getMacroCall().getExpanded() }
|
||||
|
||||
@@ -7,9 +7,70 @@ private import codeql.util.Unit
|
||||
private import codeql.dataflow.DataFlow
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
private import rust
|
||||
private import SsaImpl as SsaImpl
|
||||
private import codeql.rust.controlflow.ControlFlowGraph
|
||||
private import codeql.rust.controlflow.CfgNodes
|
||||
private import codeql.rust.dataflow.Ssa
|
||||
|
||||
private newtype TReturnKind = TNormalReturnKind()
|
||||
|
||||
/**
|
||||
* A return kind. A return kind describes how a value can be returned from a
|
||||
* callable.
|
||||
*
|
||||
* The only return kind is a "normal" return from a `return` statement or an
|
||||
* expression body.
|
||||
*/
|
||||
final class ReturnKind extends TNormalReturnKind {
|
||||
string toString() { result = "return" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A callable. This includes callables from source code, as well as callables
|
||||
* defined in library code.
|
||||
*/
|
||||
final class DataFlowCallable extends TDataFlowCallable {
|
||||
/**
|
||||
* Gets the underlying CFG scope, if any.
|
||||
*/
|
||||
CfgScope asCfgScope() { this = TCfgScope(result) }
|
||||
|
||||
/** Gets a textual representation of this callable. */
|
||||
string toString() { result = this.asCfgScope().toString() }
|
||||
|
||||
/** Gets the location of this callable. */
|
||||
Location getLocation() { result = this.asCfgScope().getLocation() }
|
||||
}
|
||||
|
||||
abstract class DataFlowCall extends TDataFlowCall {
|
||||
/** Gets the enclosing callable. */
|
||||
abstract DataFlowCallable getEnclosingCallable();
|
||||
|
||||
/** Gets the underlying source code call, if any. */
|
||||
abstract CallCfgNode asCall();
|
||||
|
||||
/** Gets a textual representation of this call. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets the location of this call. */
|
||||
abstract Location getLocation();
|
||||
}
|
||||
|
||||
final class NormalCall extends DataFlowCall, TNormalCall {
|
||||
private CallCfgNode c;
|
||||
|
||||
NormalCall() { this = TNormalCall(c) }
|
||||
|
||||
/** Gets the underlying call in the CFG, if any. */
|
||||
override CallCfgNode asCall() { result = c }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { none() }
|
||||
|
||||
override string toString() { result = c.toString() }
|
||||
|
||||
override Location getLocation() { result = c.getLocation() }
|
||||
}
|
||||
|
||||
module Node {
|
||||
/**
|
||||
* An element, viewed as a node in a data flow graph. Either an expression
|
||||
@@ -27,6 +88,12 @@ module Node {
|
||||
*/
|
||||
Expr asExpr() { none() }
|
||||
|
||||
/** Gets the enclosing callable. */
|
||||
DataFlowCallable getEnclosingCallable() { result = TCfgScope(this.getCfgScope()) }
|
||||
|
||||
/** Do not call: use `getEnclosingCallable()` instead. */
|
||||
abstract CfgScope getCfgScope();
|
||||
|
||||
/**
|
||||
* Gets the control flow node that corresponds to this data flow node.
|
||||
*/
|
||||
@@ -47,32 +114,99 @@ module Node {
|
||||
final class NaNode extends Node {
|
||||
NaNode() { none() }
|
||||
|
||||
override CfgScope getCfgScope() { none() }
|
||||
|
||||
override string toString() { result = "N/A" }
|
||||
|
||||
override Location getLocation() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node in the data flow graph that corresponds to an expression in the
|
||||
* AST.
|
||||
*
|
||||
* Note that because of control-flow splitting, one `Expr` may correspond
|
||||
* to multiple `ExprNode`s, just like it may correspond to multiple
|
||||
* `ControlFlow::Node`s.
|
||||
*/
|
||||
class ExprNode extends Node, TExprNode {
|
||||
ExprCfgNode n;
|
||||
|
||||
ExprNode() { this = TExprNode(n) }
|
||||
|
||||
override CfgScope getCfgScope() { result = this.asExpr().getEnclosingCallable() }
|
||||
|
||||
override Location getLocation() { result = n.getExpr().getLocation() }
|
||||
|
||||
override string toString() { result = n.getExpr().toString() }
|
||||
|
||||
override Expr asExpr() { result = n.getExpr() }
|
||||
|
||||
override CfgNode getCfgNode() { result = n }
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of a parameter at function entry, viewed as a node in a data
|
||||
* flow graph.
|
||||
*/
|
||||
final class ParameterNode extends Node {
|
||||
Param param;
|
||||
final class ParameterNode extends Node, TParameterNode {
|
||||
Param parameter;
|
||||
|
||||
ParameterNode() { this = TSourceParameterNode(param) }
|
||||
ParameterNode() { this = TParameterNode(parameter) }
|
||||
|
||||
override Location getLocation() { result = param.getLocation() }
|
||||
override CfgScope getCfgScope() { result = parameter.getEnclosingCallable() }
|
||||
|
||||
override string toString() { result = param.toString() }
|
||||
override Location getLocation() { result = parameter.getLocation() }
|
||||
|
||||
override string toString() { result = parameter.toString() }
|
||||
|
||||
/** Gets the parameter in the AST that this node corresponds to. */
|
||||
Param getParameter() { result = parameter }
|
||||
}
|
||||
|
||||
final class ArgumentNode = NaNode;
|
||||
|
||||
final class ReturnNode extends NaNode {
|
||||
RustDataFlow::ReturnKind getKind() { none() }
|
||||
/** An SSA node. */
|
||||
class SsaNode extends Node, TSsaNode {
|
||||
SsaImpl::DataFlowIntegration::SsaNode node;
|
||||
SsaImpl::DefinitionExt def;
|
||||
|
||||
SsaNode() {
|
||||
this = TSsaNode(node) and
|
||||
def = node.getDefinitionExt()
|
||||
}
|
||||
|
||||
override CfgScope getCfgScope() { result = def.getBasicBlock().getScope() }
|
||||
|
||||
SsaImpl::DefinitionExt getDefinitionExt() { result = def }
|
||||
|
||||
/** Holds if this node should be hidden from path explanations. */
|
||||
abstract predicate isHidden();
|
||||
|
||||
override Location getLocation() { result = node.getLocation() }
|
||||
|
||||
override string toString() { result = node.toString() }
|
||||
}
|
||||
|
||||
final class OutNode = NaNode;
|
||||
/** A data flow node that represents a value returned by a callable. */
|
||||
final class ReturnNode extends ExprNode {
|
||||
ReturnNode() { this.getCfgNode().getASuccessor() instanceof ExitCfgNode }
|
||||
|
||||
ReturnKind getKind() { any() }
|
||||
}
|
||||
|
||||
/** A data-flow node that represents the output of a call. */
|
||||
abstract class OutNode extends Node, ExprNode {
|
||||
/** Gets the underlying call for this node. */
|
||||
abstract DataFlowCall getCall();
|
||||
}
|
||||
|
||||
final private class ExprOutNode extends OutNode {
|
||||
ExprOutNode() { this.asExpr() instanceof CallExpr }
|
||||
|
||||
/** Gets the underlying call CFG node that includes this out node. */
|
||||
override DataFlowCall getCall() { result.(NormalCall).asCall() = this.getCfgNode() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node associated with an object after an operation that might have
|
||||
@@ -93,6 +227,70 @@ module Node {
|
||||
final class CastNode = NaNode;
|
||||
}
|
||||
|
||||
final class Node = Node::Node;
|
||||
|
||||
/** Provides logic related to SSA. */
|
||||
module SsaFlow {
|
||||
private module Impl = SsaImpl::DataFlowIntegration;
|
||||
|
||||
private Node::ParameterNode toParameterNode(Param p) { result = TParameterNode(p) }
|
||||
|
||||
/** Converts a control flow node into an SSA control flow node. */
|
||||
Impl::Node asNode(Node n) {
|
||||
n = TSsaNode(result)
|
||||
or
|
||||
result.(Impl::ExprNode).getExpr() = n.(Node::ExprNode).getCfgNode()
|
||||
or
|
||||
n = toParameterNode(result.(Impl::ParameterNode).getParameter())
|
||||
}
|
||||
|
||||
predicate localFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
|
||||
Impl::localFlowStep(def, asNode(nodeFrom), asNode(nodeTo), isUseStep)
|
||||
}
|
||||
|
||||
predicate localMustFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
|
||||
Impl::localMustFlowStep(def, asNode(nodeFrom), asNode(nodeTo))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds for expressions `e` that evaluate to the value of any last (in
|
||||
* evaluation order) subexpressions within it. E.g., expressions that propagate
|
||||
* a values from a subexpression.
|
||||
*
|
||||
* For instance, the predicate holds for if expressions as `if b { e1 } else {
|
||||
* e2 }` evalates to the value of one of the subexpressions `e1` or `e2`.
|
||||
*/
|
||||
private predicate propagatesValue(Expr e) {
|
||||
e instanceof IfExpr or
|
||||
e instanceof LoopExpr or
|
||||
e instanceof ReturnExpr or
|
||||
e instanceof BreakExpr or
|
||||
e.(BlockExpr).getStmtList().hasTailExpr() or
|
||||
e instanceof MatchExpr
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node that may execute last in `n`, and which, when it executes last,
|
||||
* will be the value of `n`.
|
||||
*/
|
||||
private ExprCfgNode getALastEvalNode(ExprCfgNode n) {
|
||||
propagatesValue(n.getExpr()) and result.getASuccessor() = n
|
||||
}
|
||||
|
||||
module LocalFlow {
|
||||
pragma[nomagic]
|
||||
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
|
||||
nodeFrom.getCfgNode() = getALastEvalNode(nodeTo.getCfgNode())
|
||||
}
|
||||
}
|
||||
|
||||
private class DataFlowCallableAlias = DataFlowCallable;
|
||||
|
||||
private class ReturnKindAlias = ReturnKind;
|
||||
|
||||
private class DataFlowCallAlias = DataFlowCall;
|
||||
|
||||
module RustDataFlow implements InputSig<Location> {
|
||||
/**
|
||||
* An element, viewed as a node in a data flow graph. Either an expression
|
||||
@@ -116,38 +314,36 @@ module RustDataFlow implements InputSig<Location> {
|
||||
|
||||
predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) { none() }
|
||||
|
||||
DataFlowCallable nodeGetEnclosingCallable(Node node) { none() }
|
||||
DataFlowCallable nodeGetEnclosingCallable(Node node) { result = node.getEnclosingCallable() }
|
||||
|
||||
DataFlowType getNodeType(Node node) { none() }
|
||||
DataFlowType getNodeType(Node node) { any() }
|
||||
|
||||
predicate nodeIsHidden(Node node) { none() }
|
||||
|
||||
class DataFlowExpr = Void;
|
||||
class DataFlowExpr = ExprCfgNode;
|
||||
|
||||
/** Gets the node corresponding to `e`. */
|
||||
Node exprNode(DataFlowExpr e) { none() }
|
||||
Node exprNode(DataFlowExpr e) { result.getCfgNode() = e }
|
||||
|
||||
final class DataFlowCall extends TNormalCall {
|
||||
private CallExpr c;
|
||||
final class DataFlowCall = DataFlowCallAlias;
|
||||
|
||||
DataFlowCall() { this = TNormalCall(c) }
|
||||
final class DataFlowCallable = DataFlowCallableAlias;
|
||||
|
||||
DataFlowCallable getEnclosingCallable() { none() }
|
||||
|
||||
string toString() { result = c.toString() }
|
||||
|
||||
Location getLocation() { result = c.getLocation() }
|
||||
}
|
||||
|
||||
final class DataFlowCallable = CfgScope;
|
||||
|
||||
final class ReturnKind = Void;
|
||||
final class ReturnKind = ReturnKindAlias;
|
||||
|
||||
/** Gets a viable implementation of the target of the given `Call`. */
|
||||
DataFlowCallable viableCallable(DataFlowCall c) { none() }
|
||||
|
||||
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) { none() }
|
||||
/**
|
||||
* Gets a node that can read the value returned from `call` with return kind
|
||||
* `kind`.
|
||||
*/
|
||||
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
|
||||
call = result.getCall() and exists(kind)
|
||||
}
|
||||
|
||||
// NOTE: For now we use the type `Unit` and do not benefit from type
|
||||
// information in the data flow analysis.
|
||||
final class DataFlowType = Unit;
|
||||
|
||||
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { any() }
|
||||
@@ -191,7 +387,7 @@ module RustDataFlow implements InputSig<Location> {
|
||||
* Holds if there is a simple local flow step from `node1` to `node2`. These
|
||||
* are the value-preserving intra-callable flow steps.
|
||||
*/
|
||||
predicate simpleLocalFlowStep(Node node1, Node node2, string model) { none() }
|
||||
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) { none() }
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` through a non-local step
|
||||
@@ -256,7 +452,9 @@ module RustDataFlow implements InputSig<Location> {
|
||||
* `node2` must be visited along a flow path, then any type known for `node2`
|
||||
* must also apply to `node1`.
|
||||
*/
|
||||
predicate localMustFlowStep(Node node1, Node node2) { none() }
|
||||
predicate localMustFlowStep(Node node1, Node node2) {
|
||||
SsaFlow::localMustFlowStep(_, node1, node2)
|
||||
}
|
||||
|
||||
class LambdaCallKind = Void;
|
||||
|
||||
@@ -267,7 +465,7 @@ module RustDataFlow implements InputSig<Location> {
|
||||
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { none() }
|
||||
|
||||
/** Extra data-flow steps needed for lambda flow analysis. */
|
||||
/** Extra data flow steps needed for lambda flow analysis. */
|
||||
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() }
|
||||
|
||||
predicate knownSourceModel(Node source, string model) { none() }
|
||||
@@ -286,11 +484,12 @@ cached
|
||||
private module Cached {
|
||||
cached
|
||||
newtype TNode =
|
||||
TExprNode(CfgNode n, Expr e) { n.getAstNode() = e } or
|
||||
TSourceParameterNode(Param param)
|
||||
TExprNode(ExprCfgNode n) or
|
||||
TParameterNode(Param p) or
|
||||
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node)
|
||||
|
||||
cached
|
||||
newtype TDataFlowCall = TNormalCall(CallExpr c)
|
||||
newtype TDataFlowCall = TNormalCall(CallCfgNode c)
|
||||
|
||||
cached
|
||||
newtype TOptionalContentSet =
|
||||
@@ -300,9 +499,16 @@ private module Cached {
|
||||
cached
|
||||
class TContentSet = TAnyElementContent or TAnyContent;
|
||||
|
||||
cached
|
||||
newtype TDataFlowCallable = TCfgScope(CfgScope scope)
|
||||
|
||||
/** This is the local flow predicate that is exposed. */
|
||||
cached
|
||||
predicate localFlowStepImpl(Node::Node nodeFrom, Node::Node nodeTo) { none() }
|
||||
predicate localFlowStepImpl(Node::Node nodeFrom, Node::Node nodeTo) {
|
||||
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
|
||||
or
|
||||
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
|
||||
@@ -2,6 +2,7 @@ private import rust
|
||||
private import codeql.rust.controlflow.BasicBlocks as BasicBlocks
|
||||
private import BasicBlocks
|
||||
private import codeql.rust.controlflow.ControlFlowGraph as Cfg
|
||||
private import codeql.rust.controlflow.CfgNodes as CfgNodes
|
||||
private import Cfg
|
||||
private import codeql.rust.controlflow.internal.ControlFlowGraphImpl as ControlFlowGraphImpl
|
||||
private import codeql.ssa.Ssa as SsaImplCommon
|
||||
@@ -395,6 +396,38 @@ private module Cached {
|
||||
Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) {
|
||||
Impl::uncertainWriteDefinitionInput(def, result)
|
||||
}
|
||||
|
||||
cached
|
||||
module DataFlowIntegration {
|
||||
import DataFlowIntegrationImpl
|
||||
|
||||
cached
|
||||
predicate localFlowStep(DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
|
||||
DataFlowIntegrationImpl::localFlowStep(def, nodeFrom, nodeTo, isUseStep)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate localMustFlowStep(DefinitionExt def, Node nodeFrom, Node nodeTo) {
|
||||
DataFlowIntegrationImpl::localMustFlowStep(def, nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
signature predicate guardChecksSig(CfgNodes::AstCfgNode g, Cfg::CfgNode e, boolean branch);
|
||||
|
||||
cached // nothing is actually cached
|
||||
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
private predicate guardChecksAdjTypes(
|
||||
DataFlowIntegrationInput::Guard g, DataFlowIntegrationInput::Expr e, boolean branch
|
||||
) {
|
||||
guardChecks(g, e, branch)
|
||||
}
|
||||
|
||||
private Node getABarrierNodeImpl() {
|
||||
result = DataFlowIntegrationImpl::BarrierGuard<guardChecksAdjTypes/3>::getABarrierNode()
|
||||
}
|
||||
|
||||
predicate getABarrierNode = getABarrierNodeImpl/0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
@@ -426,3 +459,46 @@ class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
|
||||
|
||||
override Location getLocation() { result = Impl::PhiReadNode.super.getLocation() }
|
||||
}
|
||||
|
||||
private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInputSig {
|
||||
class Expr extends CfgNodes::AstCfgNode {
|
||||
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
|
||||
}
|
||||
|
||||
Expr getARead(Definition def) { result = Cached::getARead(def) }
|
||||
|
||||
/** Holds if SSA definition `def` assigns `value` to the underlying variable. */
|
||||
predicate ssaDefAssigns(WriteDefinition def, Expr value) {
|
||||
exists(BasicBlock bb, int i | def.definesAt(_, bb, i) and value = bb.getNode(i))
|
||||
}
|
||||
|
||||
class Parameter = Param;
|
||||
|
||||
/** Holds if SSA definition `def` initializes parameter `p` at function entry. */
|
||||
predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) {
|
||||
exists(BasicBlock bb, int i | bb.getNode(i).getAstNode() = p and def.definesAt(_, bb, i))
|
||||
}
|
||||
|
||||
class Guard extends CfgNodes::AstCfgNode {
|
||||
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
|
||||
}
|
||||
|
||||
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
|
||||
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
exists(ConditionBlock conditionBlock, ConditionalSuccessor s |
|
||||
guard = conditionBlock.getLastNode() and
|
||||
s.getValue() = branch and
|
||||
conditionBlock.controls(bb, s)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets an immediate conditional successor of basic block `bb`, if any. */
|
||||
SsaInput::BasicBlock getAConditionalBasicBlockSuccessor(SsaInput::BasicBlock bb, boolean branch) {
|
||||
exists(Cfg::ConditionalSuccessor s |
|
||||
result = bb.getASuccessor(s) and
|
||||
s.getValue() = branch
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;
|
||||
|
||||
21
rust/ql/src/queries/diagnostics/DataFlowConsistencyCounts.ql
Normal file
21
rust/ql/src/queries/diagnostics/DataFlowConsistencyCounts.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @name Data flow inconsistency counts
|
||||
* @description Counts the number of data flow inconsistencies of each type. This query is intended for internal use.
|
||||
* @kind diagnostic
|
||||
* @id rust/diagnostics/data-flow-consistency-counts
|
||||
*/
|
||||
|
||||
private import rust
|
||||
private import codeql.rust.dataflow.internal.DataFlowImpl
|
||||
private import codeql.rust.dataflow.internal.TaintTrackingImpl
|
||||
private import codeql.dataflow.internal.DataFlowImplConsistency
|
||||
|
||||
private module Input implements InputSig<Location, RustDataFlow> { }
|
||||
|
||||
// see also `rust/diagnostics/data-flow-consistency`, which lists the
|
||||
// individual inconsistency results.
|
||||
from string type, int num
|
||||
where
|
||||
num =
|
||||
MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>::getInconsistencyCounts(type)
|
||||
select type, num
|
||||
@@ -3,8 +3,11 @@
|
||||
*/
|
||||
|
||||
import rust
|
||||
import codeql.rust.AstConsistency as AstConsistency
|
||||
private import codeql.rust.dataflow.internal.DataFlowImpl
|
||||
private import codeql.rust.dataflow.internal.TaintTrackingImpl
|
||||
private import codeql.rust.AstConsistency as AstConsistency
|
||||
private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency
|
||||
private import codeql.dataflow.internal.DataFlowImplConsistency as DataFlowImplConsistency
|
||||
|
||||
/**
|
||||
* Gets a count of the total number of lines of code in the database.
|
||||
@@ -31,3 +34,16 @@ int getTotalAstInconsistencies() {
|
||||
int getTotalCfgInconsistencies() {
|
||||
result = sum(string type | | CfgConsistency::getCfgInconsistencyCounts(type))
|
||||
}
|
||||
|
||||
private module Input implements DataFlowImplConsistency::InputSig<Location, RustDataFlow> { }
|
||||
|
||||
/**
|
||||
* Gets a count of the total number of data flow inconsistencies in the database.
|
||||
*/
|
||||
int getTotalDataFlowInconsistencies() {
|
||||
result =
|
||||
sum(string type |
|
||||
|
|
||||
DataFlowImplConsistency::MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>::getInconsistencyCounts(type)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -35,4 +35,6 @@ where
|
||||
key = "Inconsistencies - AST" and value = getTotalAstInconsistencies()
|
||||
or
|
||||
key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies()
|
||||
or
|
||||
key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies()
|
||||
select key, value
|
||||
|
||||
@@ -1,8 +1,2 @@
|
||||
uniqueEnclosingCallable
|
||||
| gen_become_expr.rs:4:11:4:16 | Param | Node should have one enclosing callable but has 0. |
|
||||
| gen_become_expr.rs:4:19:4:24 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueCallEnclosingCallable
|
||||
| gen_become_expr.rs:8:17:8:36 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| gen_become_expr.rs:4:11:4:16 | Param | Node should have one type but has 0. |
|
||||
| gen_become_expr.rs:4:19:4:24 | Param | Node should have one type but has 0. |
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
| gen_closure_expr.rs:5:6:5:6 | Param | Node should have one enclosing callable but has 0. |
|
||||
| gen_closure_expr.rs:6:11:6:16 | Param | Node should have one enclosing callable but has 0. |
|
||||
| gen_closure_expr.rs:7:12:7:17 | Param | Node should have one enclosing callable but has 0. |
|
||||
| gen_closure_expr.rs:7:20:7:20 | Param | Node should have one enclosing callable but has 0. |
|
||||
| gen_closure_expr.rs:9:6:9:6 | Param | Node should have one enclosing callable but has 0. |
|
||||
| gen_closure_expr.rs:11:14:11:14 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| gen_closure_expr.rs:5:6:5:6 | Param | Node should have one type but has 0. |
|
||||
| gen_closure_expr.rs:6:11:6:16 | Param | Node should have one type but has 0. |
|
||||
| gen_closure_expr.rs:7:12:7:17 | Param | Node should have one type but has 0. |
|
||||
| gen_closure_expr.rs:7:20:7:20 | Param | Node should have one type but has 0. |
|
||||
| gen_closure_expr.rs:9:6:9:6 | Param | Node should have one type but has 0. |
|
||||
| gen_closure_expr.rs:11:14:11:14 | Param | Node should have one type but has 0. |
|
||||
@@ -1,3 +1,2 @@
|
||||
uniqueCallEnclosingCallable
|
||||
| gen_continue_expr.rs:6:12:6:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| gen_continue_expr.rs:11:12:11:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
| gen_function.rs:4:8:4:13 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| gen_function.rs:4:8:4:13 | Param | Node should have one type but has 0. |
|
||||
@@ -1,6 +1,2 @@
|
||||
uniqueEnclosingCallable
|
||||
| gen_let_expr.rs:3:18:3:43 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueCallEnclosingCallable
|
||||
| gen_let_expr.rs:6:18:6:24 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| gen_let_expr.rs:3:18:3:43 | Param | Node should have one type but has 0. |
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
uniqueCallEnclosingCallable
|
||||
| gen_loop_expr.rs:6:18:6:40 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| gen_loop_expr.rs:9:18:9:39 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
uniqueEnclosingCallable
|
||||
| common_definitions.rs:3:15:3:25 | Param | Node should have one enclosing callable but has 0. |
|
||||
| file://:0:0:0:0 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| common_definitions.rs:3:15:3:25 | Param | Node should have one type but has 0. |
|
||||
| file://:0:0:0:0 | Param | Node should have one type but has 0. |
|
||||
uniqueNodeLocation
|
||||
| file://:0:0:0:0 | BlockExpr | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | MethodCallExpr | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | MethodCallExpr | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | Param | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | PathExpr | Node should have one location but has 0. |
|
||||
missingLocation
|
||||
| Nodes without location: 1 |
|
||||
| Nodes without location: 5 |
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
| gen_match_arm.rs:3:19:3:24 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| gen_match_arm.rs:3:19:3:24 | Param | Node should have one type but has 0. |
|
||||
@@ -1,4 +0,0 @@
|
||||
uniqueEnclosingCallable
|
||||
| gen_match_expr.rs:3:20:3:25 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| gen_match_expr.rs:3:20:3:25 | Param | Node should have one type but has 0. |
|
||||
@@ -1,4 +1,2 @@
|
||||
uniqueEnclosingCallable
|
||||
| gen_trait.rs:7:32:7:60 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| gen_trait.rs:7:32:7:60 | Param | Node should have one type but has 0. |
|
||||
|
||||
@@ -1,51 +1,4 @@
|
||||
uniqueEnclosingCallable
|
||||
| test.rs:18:32:18:37 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:36:31:36:37 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:50:34:50:40 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:64:34:64:40 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:78:19:78:24 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:98:17:98:22 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:114:25:114:30 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:115:20:115:20 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:121:21:121:26 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:129:25:129:38 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:137:20:137:33 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:144:23:144:28 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:152:29:152:34 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:163:29:163:34 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:174:27:174:32 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:183:22:183:27 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:196:22:196:27 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:209:28:209:33 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:222:26:222:32 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:222:35:222:41 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:222:44:222:50 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:227:25:227:31 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:227:34:227:40 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:227:43:227:49 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:232:27:232:33 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:232:36:232:41 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:232:44:232:50 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:237:26:237:32 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:242:29:242:35 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:242:38:242:43 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:242:46:242:52 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:250:28:250:34 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:250:37:250:42 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:250:45:250:51 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:258:29:258:35 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:269:38:269:44 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:273:38:273:52 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:283:19:283:42 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:291:44:291:67 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:302:23:302:32 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:302:35:302:48 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:309:35:309:58 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:319:23:319:36 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:324:29:324:42 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:335:28:335:35 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:342:29:342:40 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:401:15:401:25 | Param | Node should have one enclosing callable but has 0. |
|
||||
| test.rs:408:16:408:19 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueCallEnclosingCallable
|
||||
| test.rs:6:9:6:44 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -63,52 +16,3 @@ uniqueCallEnclosingCallable
|
||||
| test.rs:381:12:381:30 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| test.rs:384:9:384:23 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| test.rs:404:5:404:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| test.rs:18:32:18:37 | Param | Node should have one type but has 0. |
|
||||
| test.rs:36:31:36:37 | Param | Node should have one type but has 0. |
|
||||
| test.rs:50:34:50:40 | Param | Node should have one type but has 0. |
|
||||
| test.rs:64:34:64:40 | Param | Node should have one type but has 0. |
|
||||
| test.rs:78:19:78:24 | Param | Node should have one type but has 0. |
|
||||
| test.rs:98:17:98:22 | Param | Node should have one type but has 0. |
|
||||
| test.rs:114:25:114:30 | Param | Node should have one type but has 0. |
|
||||
| test.rs:115:20:115:20 | Param | Node should have one type but has 0. |
|
||||
| test.rs:121:21:121:26 | Param | Node should have one type but has 0. |
|
||||
| test.rs:129:25:129:38 | Param | Node should have one type but has 0. |
|
||||
| test.rs:137:20:137:33 | Param | Node should have one type but has 0. |
|
||||
| test.rs:144:23:144:28 | Param | Node should have one type but has 0. |
|
||||
| test.rs:152:29:152:34 | Param | Node should have one type but has 0. |
|
||||
| test.rs:163:29:163:34 | Param | Node should have one type but has 0. |
|
||||
| test.rs:174:27:174:32 | Param | Node should have one type but has 0. |
|
||||
| test.rs:183:22:183:27 | Param | Node should have one type but has 0. |
|
||||
| test.rs:196:22:196:27 | Param | Node should have one type but has 0. |
|
||||
| test.rs:209:28:209:33 | Param | Node should have one type but has 0. |
|
||||
| test.rs:222:26:222:32 | Param | Node should have one type but has 0. |
|
||||
| test.rs:222:35:222:41 | Param | Node should have one type but has 0. |
|
||||
| test.rs:222:44:222:50 | Param | Node should have one type but has 0. |
|
||||
| test.rs:227:25:227:31 | Param | Node should have one type but has 0. |
|
||||
| test.rs:227:34:227:40 | Param | Node should have one type but has 0. |
|
||||
| test.rs:227:43:227:49 | Param | Node should have one type but has 0. |
|
||||
| test.rs:232:27:232:33 | Param | Node should have one type but has 0. |
|
||||
| test.rs:232:36:232:41 | Param | Node should have one type but has 0. |
|
||||
| test.rs:232:44:232:50 | Param | Node should have one type but has 0. |
|
||||
| test.rs:237:26:237:32 | Param | Node should have one type but has 0. |
|
||||
| test.rs:242:29:242:35 | Param | Node should have one type but has 0. |
|
||||
| test.rs:242:38:242:43 | Param | Node should have one type but has 0. |
|
||||
| test.rs:242:46:242:52 | Param | Node should have one type but has 0. |
|
||||
| test.rs:250:28:250:34 | Param | Node should have one type but has 0. |
|
||||
| test.rs:250:37:250:42 | Param | Node should have one type but has 0. |
|
||||
| test.rs:250:45:250:51 | Param | Node should have one type but has 0. |
|
||||
| test.rs:258:29:258:35 | Param | Node should have one type but has 0. |
|
||||
| test.rs:269:38:269:44 | Param | Node should have one type but has 0. |
|
||||
| test.rs:273:38:273:52 | Param | Node should have one type but has 0. |
|
||||
| test.rs:283:19:283:42 | Param | Node should have one type but has 0. |
|
||||
| test.rs:291:44:291:67 | Param | Node should have one type but has 0. |
|
||||
| test.rs:302:23:302:32 | Param | Node should have one type but has 0. |
|
||||
| test.rs:302:35:302:48 | Param | Node should have one type but has 0. |
|
||||
| test.rs:309:35:309:58 | Param | Node should have one type but has 0. |
|
||||
| test.rs:319:23:319:36 | Param | Node should have one type but has 0. |
|
||||
| test.rs:324:29:324:42 | Param | Node should have one type but has 0. |
|
||||
| test.rs:335:28:335:35 | Param | Node should have one type but has 0. |
|
||||
| test.rs:342:29:342:40 | Param | Node should have one type but has 0. |
|
||||
| test.rs:401:15:401:25 | Param | Node should have one type but has 0. |
|
||||
| test.rs:408:16:408:19 | Param | Node should have one type but has 0. |
|
||||
|
||||
@@ -313,7 +313,8 @@ edges
|
||||
| test.rs:153:9:160:9 | IfExpr | test.rs:152:44:161:5 | BlockExpr | |
|
||||
| test.rs:153:13:156:9 | [boolean(false)] MatchExpr | test.rs:159:13:159:13 | 0 | false |
|
||||
| test.rs:153:13:156:9 | [boolean(true)] MatchExpr | test.rs:157:13:157:13 | 1 | true |
|
||||
| test.rs:153:19:153:19 | a | test.rs:154:13:154:13 | LiteralPat | |
|
||||
| test.rs:153:19:153:19 | a | test.rs:154:13:154:13 | 0 | |
|
||||
| test.rs:154:13:154:13 | 0 | test.rs:154:13:154:13 | LiteralPat | |
|
||||
| test.rs:154:13:154:13 | LiteralPat | test.rs:154:18:154:21 | true | match |
|
||||
| test.rs:154:13:154:13 | LiteralPat | test.rs:155:13:155:13 | WildcardPat | no-match |
|
||||
| test.rs:154:18:154:21 | true | test.rs:153:13:156:9 | [boolean(true)] MatchExpr | true |
|
||||
@@ -590,13 +591,15 @@ edges
|
||||
| test.rs:274:9:277:9 | MatchExpr | test.rs:273:71:278:5 | BlockExpr | |
|
||||
| test.rs:274:15:274:15 | b | test.rs:274:15:274:16 | TryExpr | |
|
||||
| test.rs:274:15:274:16 | TryExpr | test.rs:273:5:278:5 | exit test_question_mark_operator_2 (normal) | return |
|
||||
| test.rs:274:15:274:16 | TryExpr | test.rs:275:13:275:16 | LiteralPat | match |
|
||||
| test.rs:274:15:274:16 | TryExpr | test.rs:275:13:275:16 | true | match |
|
||||
| test.rs:275:13:275:16 | LiteralPat | test.rs:275:21:275:24 | PathExpr | match |
|
||||
| test.rs:275:13:275:16 | LiteralPat | test.rs:276:13:276:17 | LiteralPat | no-match |
|
||||
| test.rs:275:13:275:16 | LiteralPat | test.rs:276:13:276:17 | false | no-match |
|
||||
| test.rs:275:13:275:16 | true | test.rs:275:13:275:16 | LiteralPat | |
|
||||
| test.rs:275:21:275:24 | PathExpr | test.rs:275:26:275:30 | false | |
|
||||
| test.rs:275:21:275:31 | CallExpr | test.rs:274:9:277:9 | MatchExpr | |
|
||||
| test.rs:275:26:275:30 | false | test.rs:275:21:275:31 | CallExpr | |
|
||||
| test.rs:276:13:276:17 | LiteralPat | test.rs:276:22:276:25 | PathExpr | match |
|
||||
| test.rs:276:13:276:17 | false | test.rs:276:13:276:17 | LiteralPat | |
|
||||
| test.rs:276:22:276:25 | PathExpr | test.rs:276:27:276:30 | true | |
|
||||
| test.rs:276:22:276:31 | CallExpr | test.rs:274:9:277:9 | MatchExpr | |
|
||||
| test.rs:276:27:276:30 | true | test.rs:276:22:276:31 | CallExpr | |
|
||||
@@ -735,21 +738,25 @@ edges
|
||||
| test.rs:348:31:355:5 | BlockExpr | test.rs:348:5:355:5 | exit range_pattern (normal) | |
|
||||
| test.rs:349:9:354:9 | MatchExpr | test.rs:348:31:355:5 | BlockExpr | |
|
||||
| test.rs:349:15:349:16 | 42 | test.rs:350:13:350:15 | RangePat | |
|
||||
| test.rs:350:13:350:15 | RangePat | test.rs:350:15:350:15 | LiteralPat | match |
|
||||
| test.rs:350:13:350:15 | RangePat | test.rs:350:15:350:15 | 0 | match |
|
||||
| test.rs:350:13:350:15 | RangePat | test.rs:351:13:351:16 | RangePat | no-match |
|
||||
| test.rs:350:15:350:15 | 0 | test.rs:350:15:350:15 | LiteralPat | |
|
||||
| test.rs:350:15:350:15 | LiteralPat | test.rs:350:20:350:20 | 1 | match |
|
||||
| test.rs:350:15:350:15 | LiteralPat | test.rs:351:13:351:16 | RangePat | no-match |
|
||||
| test.rs:350:20:350:20 | 1 | test.rs:349:9:354:9 | MatchExpr | |
|
||||
| test.rs:351:13:351:13 | LiteralPat | test.rs:351:16:351:16 | LiteralPat | match |
|
||||
| test.rs:351:13:351:13 | 1 | test.rs:351:13:351:13 | LiteralPat | |
|
||||
| test.rs:351:13:351:13 | LiteralPat | test.rs:351:16:351:16 | 2 | match |
|
||||
| test.rs:351:13:351:13 | LiteralPat | test.rs:352:13:352:15 | RangePat | no-match |
|
||||
| test.rs:351:13:351:16 | RangePat | test.rs:351:13:351:13 | LiteralPat | match |
|
||||
| test.rs:351:13:351:16 | RangePat | test.rs:351:13:351:13 | 1 | match |
|
||||
| test.rs:351:13:351:16 | RangePat | test.rs:352:13:352:15 | RangePat | no-match |
|
||||
| test.rs:351:16:351:16 | 2 | test.rs:351:16:351:16 | LiteralPat | |
|
||||
| test.rs:351:16:351:16 | LiteralPat | test.rs:351:21:351:21 | 2 | match |
|
||||
| test.rs:351:16:351:16 | LiteralPat | test.rs:352:13:352:15 | RangePat | no-match |
|
||||
| test.rs:351:21:351:21 | 2 | test.rs:349:9:354:9 | MatchExpr | |
|
||||
| test.rs:352:13:352:13 | 5 | test.rs:352:13:352:13 | LiteralPat | |
|
||||
| test.rs:352:13:352:13 | LiteralPat | test.rs:352:20:352:20 | 3 | match |
|
||||
| test.rs:352:13:352:13 | LiteralPat | test.rs:353:13:353:14 | RestPat | no-match |
|
||||
| test.rs:352:13:352:15 | RangePat | test.rs:352:13:352:13 | LiteralPat | match |
|
||||
| test.rs:352:13:352:15 | RangePat | test.rs:352:13:352:13 | 5 | match |
|
||||
| test.rs:352:13:352:15 | RangePat | test.rs:353:13:353:14 | RestPat | no-match |
|
||||
| test.rs:352:20:352:20 | 3 | test.rs:349:9:354:9 | MatchExpr | |
|
||||
| test.rs:353:13:353:14 | RestPat | test.rs:353:19:353:19 | 4 | match |
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
uniqueEnclosingCallable
|
||||
| main.rs:5:9:5:15 | Param | Node should have one enclosing callable but has 0. |
|
||||
| main.rs:9:13:9:19 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueCallEnclosingCallable
|
||||
| main.rs:6:14:6:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| main.rs:17:13:17:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -10,6 +7,3 @@ uniqueCallEnclosingCallable
|
||||
| main.rs:24:5:24:11 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| main.rs:28:13:28:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| main.rs:29:5:29:11 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| main.rs:5:9:5:15 | Param | Node should have one type but has 0. |
|
||||
| main.rs:9:13:9:19 | Param | Node should have one type but has 0. |
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
uniqueCallEnclosingCallable
|
||||
| main.rs:3:14:3:33 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| main.rs:7:5:7:14 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| main.rs:39:5:39:14 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| main.rs:40:5:40:23 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
| main.rs:2:9:2:9 | s | main.rs:3:33:3:33 | s |
|
||||
| main.rs:6:18:6:21 | cond | main.rs:9:16:9:19 | cond |
|
||||
| main.rs:7:9:7:9 | a | main.rs:10:9:10:9 | a |
|
||||
| main.rs:8:9:8:9 | b | main.rs:12:9:12:9 | b |
|
||||
| main.rs:9:9:9:9 | c | main.rs:14:5:14:5 | c |
|
||||
| main.rs:9:21:11:5 | BlockExpr | main.rs:9:13:13:5 | IfExpr |
|
||||
| main.rs:10:9:10:9 | a | main.rs:9:21:11:5 | BlockExpr |
|
||||
| main.rs:11:12:13:5 | BlockExpr | main.rs:9:13:13:5 | IfExpr |
|
||||
| main.rs:12:9:12:9 | b | main.rs:11:12:13:5 | BlockExpr |
|
||||
| main.rs:14:5:14:5 | c | main.rs:6:37:15:1 | BlockExpr |
|
||||
| main.rs:18:9:18:9 | a | main.rs:20:15:20:15 | a |
|
||||
| main.rs:19:9:19:9 | b | main.rs:22:5:22:5 | b |
|
||||
| main.rs:20:9:20:15 | BreakExpr | main.rs:19:13:21:5 | LoopExpr |
|
||||
| main.rs:20:15:20:15 | a | main.rs:20:9:20:15 | BreakExpr |
|
||||
| main.rs:22:5:22:5 | b | main.rs:17:29:23:1 | BlockExpr |
|
||||
| main.rs:27:5:27:5 | i | main.rs:27:5:27:5 | i |
|
||||
| main.rs:27:5:27:5 | i | main.rs:28:5:28:5 | i |
|
||||
| main.rs:28:5:28:5 | i | main.rs:25:24:29:1 | BlockExpr |
|
||||
| main.rs:31:21:31:21 | a | main.rs:33:20:33:20 | a |
|
||||
| main.rs:31:29:31:29 | b | main.rs:34:17:34:17 | b |
|
||||
| main.rs:31:37:31:37 | c | main.rs:32:11:32:11 | c |
|
||||
| main.rs:32:5:35:5 | MatchExpr | main.rs:31:60:36:1 | BlockExpr |
|
||||
| main.rs:33:20:33:20 | a | main.rs:32:5:35:5 | MatchExpr |
|
||||
| main.rs:34:17:34:17 | b | main.rs:32:5:35:5 | MatchExpr |
|
||||
|
||||
@@ -3,6 +3,39 @@ fn variable() {
|
||||
println!("{:?} data flow!", s);
|
||||
}
|
||||
|
||||
fn if_expression(cond: bool) -> i64 {
|
||||
let a = 1;
|
||||
let b = 2;
|
||||
let c = if cond {
|
||||
a
|
||||
} else {
|
||||
b
|
||||
};
|
||||
c
|
||||
}
|
||||
|
||||
fn loop_expression() -> i64 {
|
||||
let a = 1;
|
||||
let b = loop {
|
||||
break a;
|
||||
};
|
||||
b
|
||||
}
|
||||
|
||||
fn assignment() -> i64 {
|
||||
let mut i = 1;
|
||||
i = 2;
|
||||
i
|
||||
}
|
||||
|
||||
fn match_expression(a: i64, b: i64, c: Option<i64>) -> i64 {
|
||||
match c {
|
||||
Some(_) => a,
|
||||
None => b,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
variable();
|
||||
if_expression(true);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,3 @@
|
||||
uniqueEnclosingCallable
|
||||
| variables.rs:3:14:3:20 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:7:14:7:19 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:11:18:11:24 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:261:5:261:12 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:262:5:265:19 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:272:5:272:50 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:316:10:316:15 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:324:10:324:15 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:356:17:356:28 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:363:22:363:36 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:363:39:363:57 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:435:8:435:15 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:451:13:451:21 | Param | Node should have one enclosing callable but has 0. |
|
||||
| variables.rs:451:24:451:32 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueCallEnclosingCallable
|
||||
| variables.rs:4:14:4:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| variables.rs:8:14:8:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -158,18 +143,3 @@ uniqueCallEnclosingCallable
|
||||
| variables.rs:542:5:542:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| variables.rs:543:5:543:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| variables.rs:544:5:544:29 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
| variables.rs:3:14:3:20 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:7:14:7:19 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:11:18:11:24 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:261:5:261:12 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:262:5:265:19 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:272:5:272:50 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:316:10:316:15 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:324:10:324:15 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:356:17:356:28 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:363:22:363:36 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:363:39:363:57 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:435:8:435:15 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:451:13:451:21 | Param | Node should have one type but has 0. |
|
||||
| variables.rs:451:24:451:32 | Param | Node should have one type but has 0. |
|
||||
|
||||
@@ -260,8 +260,9 @@ edges
|
||||
| variables.rs:114:5:122:5 | ExprStmt | variables.rs:114:11:114:12 | x6 | |
|
||||
| variables.rs:114:5:122:5 | MatchExpr | variables.rs:124:5:124:18 | ExprStmt | |
|
||||
| variables.rs:114:11:114:12 | x6 | variables.rs:115:9:115:16 | TupleStructPat | |
|
||||
| variables.rs:115:9:115:16 | TupleStructPat | variables.rs:115:14:115:15 | LiteralPat | match |
|
||||
| variables.rs:115:9:115:16 | TupleStructPat | variables.rs:115:14:115:15 | 50 | match |
|
||||
| variables.rs:115:9:115:16 | TupleStructPat | variables.rs:116:9:116:16 | TupleStructPat | no-match |
|
||||
| variables.rs:115:14:115:15 | 50 | variables.rs:115:14:115:15 | LiteralPat | |
|
||||
| variables.rs:115:14:115:15 | LiteralPat | variables.rs:115:21:115:29 | PathExpr | match |
|
||||
| variables.rs:115:14:115:15 | LiteralPat | variables.rs:116:9:116:16 | TupleStructPat | no-match |
|
||||
| variables.rs:115:21:115:29 | PathExpr | variables.rs:115:31:115:38 | "Got 50" | |
|
||||
@@ -358,10 +359,12 @@ edges
|
||||
| variables.rs:172:9:174:9 | RecordPat | variables.rs:173:31:173:35 | RangePat | match |
|
||||
| variables.rs:172:9:174:9 | RecordPat | variables.rs:175:9:175:38 | RecordPat | no-match |
|
||||
| variables.rs:173:17:173:35 | [match(true)] id_variable | variables.rs:174:14:174:22 | PathExpr | match |
|
||||
| variables.rs:173:31:173:31 | LiteralPat | variables.rs:173:35:173:35 | LiteralPat | match |
|
||||
| variables.rs:173:31:173:31 | 3 | variables.rs:173:31:173:31 | LiteralPat | |
|
||||
| variables.rs:173:31:173:31 | LiteralPat | variables.rs:173:35:173:35 | 7 | match |
|
||||
| variables.rs:173:31:173:31 | LiteralPat | variables.rs:175:9:175:38 | RecordPat | no-match |
|
||||
| variables.rs:173:31:173:35 | RangePat | variables.rs:173:31:173:31 | LiteralPat | match |
|
||||
| variables.rs:173:31:173:35 | RangePat | variables.rs:173:31:173:31 | 3 | match |
|
||||
| variables.rs:173:31:173:35 | RangePat | variables.rs:175:9:175:38 | RecordPat | no-match |
|
||||
| variables.rs:173:35:173:35 | 7 | variables.rs:173:35:173:35 | LiteralPat | |
|
||||
| variables.rs:173:35:173:35 | LiteralPat | variables.rs:173:17:173:35 | [match(true)] id_variable | match |
|
||||
| variables.rs:173:35:173:35 | LiteralPat | variables.rs:175:9:175:38 | RecordPat | no-match |
|
||||
| variables.rs:174:14:174:22 | PathExpr | variables.rs:174:24:174:34 | id_variable | |
|
||||
@@ -369,10 +372,12 @@ edges
|
||||
| variables.rs:174:24:174:34 | id_variable | variables.rs:174:14:174:35 | CallExpr | |
|
||||
| variables.rs:175:9:175:38 | RecordPat | variables.rs:175:30:175:36 | RangePat | match |
|
||||
| variables.rs:175:9:175:38 | RecordPat | variables.rs:178:9:178:29 | RecordPat | no-match |
|
||||
| variables.rs:175:30:175:31 | LiteralPat | variables.rs:175:35:175:36 | LiteralPat | match |
|
||||
| variables.rs:175:30:175:31 | 10 | variables.rs:175:30:175:31 | LiteralPat | |
|
||||
| variables.rs:175:30:175:31 | LiteralPat | variables.rs:175:35:175:36 | 12 | match |
|
||||
| variables.rs:175:30:175:31 | LiteralPat | variables.rs:178:9:178:29 | RecordPat | no-match |
|
||||
| variables.rs:175:30:175:36 | RangePat | variables.rs:175:30:175:31 | LiteralPat | match |
|
||||
| variables.rs:175:30:175:36 | RangePat | variables.rs:175:30:175:31 | 10 | match |
|
||||
| variables.rs:175:30:175:36 | RangePat | variables.rs:178:9:178:29 | RecordPat | no-match |
|
||||
| variables.rs:175:35:175:36 | 12 | variables.rs:175:35:175:36 | LiteralPat | |
|
||||
| variables.rs:175:35:175:36 | LiteralPat | variables.rs:176:22:176:51 | MacroStmts | match |
|
||||
| variables.rs:175:35:175:36 | LiteralPat | variables.rs:178:9:178:29 | RecordPat | no-match |
|
||||
| variables.rs:175:43:177:9 | BlockExpr | variables.rs:171:5:180:5 | MatchExpr | |
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
| ArgumentNode is missing PostUpdateNode | 0 |
|
||||
| Call context for isUnreachableInCall is inconsistent with call graph | 0 |
|
||||
| Call context too large | 0 |
|
||||
| Call should have one enclosing callable | 7 |
|
||||
| Callable mismatch for parameter | 0 |
|
||||
| Lambda call enclosing callable mismatch | 0 |
|
||||
| Local flow step does not preserve enclosing callable | 0 |
|
||||
| Missing call for argument node | 0 |
|
||||
| Multiple calls for argument node | 0 |
|
||||
| Node and call does not share enclosing callable | 0 |
|
||||
| Node has multiple PostUpdateNodes | 0 |
|
||||
| Node should have one enclosing callable | 0 |
|
||||
| Node should have one location | 0 |
|
||||
| Node should have one toString | 0 |
|
||||
| Node should have one type | 0 |
|
||||
| Node steps to itself | 0 |
|
||||
| Nodes without location | 0 |
|
||||
| Non-unique content approximation | 0 |
|
||||
| Origin of readStep is missing a PostUpdateNode | 0 |
|
||||
| Parameter node with multiple positions | 0 |
|
||||
| Parameters with overlapping positions | 0 |
|
||||
| PostUpdateNode does not share callable with its pre-update node | 0 |
|
||||
| PostUpdateNode should have one pre-update node | 0 |
|
||||
| PostUpdateNode should not be the target of local flow | 0 |
|
||||
| PostUpdateNode should not equal its pre-update node | 0 |
|
||||
| Read step does not preserve enclosing callable | 0 |
|
||||
| Speculative step already hasM Model | 0 |
|
||||
| Store step does not preserve enclosing callable | 0 |
|
||||
| Type compatibility predicate is not reflexive | 0 |
|
||||
@@ -0,0 +1 @@
|
||||
queries/diagnostics/DataFlowConsistencyCounts.ql
|
||||
@@ -7,5 +7,6 @@
|
||||
| Files extracted - without errors | 5 |
|
||||
| Inconsistencies - AST | 0 |
|
||||
| Inconsistencies - CFG | 0 |
|
||||
| Inconsistencies - data flow | 7 |
|
||||
| Lines of code extracted | 59 |
|
||||
| Lines of user code extracted | 59 |
|
||||
|
||||
@@ -26,11 +26,11 @@ uniqueEnclosingCallable
|
||||
| main.rs:496:12:496:17 | Param | Node should have one enclosing callable but has 0. |
|
||||
| main.rs:499:18:499:23 | Param | Node should have one enclosing callable but has 0. |
|
||||
| main.rs:502:24:502:29 | Param | Node should have one enclosing callable but has 0. |
|
||||
| main.rs:382:19:382:21 | Param | Node should have one enclosing callable but has 0. |
|
||||
| main.rs:430:29:430:38 | Param | Node should have one enclosing callable but has 0. |
|
||||
| main.rs:430:41:430:56 | Param | Node should have one enclosing callable but has 0. |
|
||||
| more.rs:4:23:4:28 | Param | Node should have one enclosing callable but has 0. |
|
||||
| more.rs:8:19:8:24 | Param | Node should have one enclosing callable but has 0. |
|
||||
| more.rs:16:23:16:28 | Param | Node should have one enclosing callable but has 0. |
|
||||
| more.rs:24:9:24:14 | Param | Node should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:10:34:10:34 | Param | Node should have one enclosing callable but has 0. |
|
||||
uniqueCallEnclosingCallable
|
||||
| main.rs:13:13:13:29 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| main.rs:14:13:14:29 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -128,17 +128,13 @@ uniqueCallEnclosingCallable
|
||||
| unreachable.rs:2:5:2:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:6:5:6:24 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:10:5:10:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:19:9:19:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:21:9:21:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:25:9:25:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:27:9:27:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:30:13:30:26 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:33:13:33:26 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:37:8:37:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:39:9:39:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:42:8:42:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:43:9:43:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:46:9:46:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:48:5:48:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:50:8:50:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:51:17:51:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -146,7 +142,6 @@ uniqueCallEnclosingCallable
|
||||
| unreachable.rs:56:17:56:30 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:58:13:58:26 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:62:8:62:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:67:5:67:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:71:8:71:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:72:9:72:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:73:16:73:25 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -173,7 +168,6 @@ uniqueCallEnclosingCallable
|
||||
| unreachable.rs:111:8:111:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:112:9:112:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:114:13:114:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:114:13:114:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:115:9:115:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:116:22:116:29 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:116:22:116:29 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -181,7 +175,6 @@ uniqueCallEnclosingCallable
|
||||
| unreachable.rs:120:8:120:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:121:9:121:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:123:13:123:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:123:13:123:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:124:9:124:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:125:21:125:28 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:125:21:125:28 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -190,36 +183,24 @@ uniqueCallEnclosingCallable
|
||||
| unreachable.rs:136:13:136:26 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:139:5:139:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:141:11:141:24 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:149:5:149:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:154:9:154:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:156:9:156:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:159:8:159:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:160:15:160:20 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:161:13:161:26 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:165:13:165:26 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:169:13:169:26 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:171:9:171:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:175:12:175:17 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:177:13:177:26 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:179:9:179:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:183:12:183:17 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:185:13:185:26 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:188:5:188:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:189:5:189:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:190:5:190:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:198:22:198:41 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:199:9:199:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:202:9:202:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:205:5:205:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:207:16:207:29 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:209:9:209:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:212:9:212:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:215:5:215:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:219:19:219:38 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:220:9:220:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:224:5:224:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:226:13:226:32 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:228:9:228:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:232:5:232:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:236:8:236:13 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:237:9:237:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
@@ -228,6 +209,7 @@ uniqueCallEnclosingCallable
|
||||
| unreachable.rs:247:9:247:14 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:248:9:248:22 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
| unreachable.rs:252:5:252:18 | CallExpr | Call should have one enclosing callable but has 0. |
|
||||
<<<<<<< HEAD
|
||||
uniqueType
|
||||
| main.rs:142:5:142:10 | Param | Node should have one type but has 0. |
|
||||
| main.rs:143:5:143:10 | Param | Node should have one type but has 0. |
|
||||
@@ -261,3 +243,5 @@ uniqueType
|
||||
| more.rs:16:23:16:28 | Param | Node should have one type but has 0. |
|
||||
| more.rs:24:9:24:14 | Param | Node should have one type but has 0. |
|
||||
| unreachable.rs:10:34:10:34 | Param | Node should have one type but has 0. |
|
||||
=======
|
||||
>>>>>>> main
|
||||
|
||||
Reference in New Issue
Block a user