mirror of
https://github.com/github/codeql.git
synced 2026-05-02 04:05:14 +02:00
Merge branch 'main' into rust-saa-additions
This commit is contained in:
2
rust/extractor/src/generated/.generated.list
generated
2
rust/extractor/src/generated/.generated.list
generated
@@ -1,2 +1,2 @@
|
||||
mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7
|
||||
top.rs f7bff00786adef1f7f80825d9f613a958c92d35896ea8c3c3b077b9992dca590 f7bff00786adef1f7f80825d9f613a958c92d35896ea8c3c3b077b9992dca590
|
||||
top.rs a77ab900964451c668839aad6827ea539b8932e7c93b54a7987ece0e1bd846ba a77ab900964451c668839aad6827ea539b8932e7c93b54a7987ece0e1bd846ba
|
||||
|
||||
122
rust/extractor/src/generated/top.rs
generated
122
rust/extractor/src/generated/top.rs
generated
@@ -6232,62 +6232,44 @@ impl From<trap::Label<ParenType>> for trap::Label<TypeRef> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PathExpr {
|
||||
pub id: trap::TrapId<PathExpr>,
|
||||
pub attrs: Vec<trap::Label<Attr>>,
|
||||
pub path: Option<trap::Label<Path>>,
|
||||
pub struct PathExprBase {
|
||||
_unused: ()
|
||||
}
|
||||
|
||||
impl trap::TrapEntry for PathExpr {
|
||||
fn extract_id(&mut self) -> trap::TrapId<Self> {
|
||||
std::mem::replace(&mut self.id, trap::TrapId::Star)
|
||||
}
|
||||
|
||||
fn emit(self, id: trap::Label<Self>, out: &mut trap::Writer) {
|
||||
out.add_tuple("path_exprs", vec![id.into()]);
|
||||
for (i, v) in self.attrs.into_iter().enumerate() {
|
||||
out.add_tuple("path_expr_attrs", vec![id.into(), i.into(), v.into()]);
|
||||
}
|
||||
if let Some(v) = self.path {
|
||||
out.add_tuple("path_expr_paths", vec![id.into(), v.into()]);
|
||||
}
|
||||
}
|
||||
impl trap::TrapClass for PathExprBase {
|
||||
fn class_name() -> &'static str { "PathExprBase" }
|
||||
}
|
||||
|
||||
impl trap::TrapClass for PathExpr {
|
||||
fn class_name() -> &'static str { "PathExpr" }
|
||||
}
|
||||
|
||||
impl From<trap::Label<PathExpr>> for trap::Label<AstNode> {
|
||||
fn from(value: trap::Label<PathExpr>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExpr is a subclass of AstNode
|
||||
impl From<trap::Label<PathExprBase>> for trap::Label<AstNode> {
|
||||
fn from(value: trap::Label<PathExprBase>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExprBase is a subclass of AstNode
|
||||
unsafe {
|
||||
Self::from_untyped(value.as_untyped())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<trap::Label<PathExpr>> for trap::Label<Element> {
|
||||
fn from(value: trap::Label<PathExpr>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExpr is a subclass of Element
|
||||
impl From<trap::Label<PathExprBase>> for trap::Label<Element> {
|
||||
fn from(value: trap::Label<PathExprBase>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExprBase is a subclass of Element
|
||||
unsafe {
|
||||
Self::from_untyped(value.as_untyped())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<trap::Label<PathExpr>> for trap::Label<Expr> {
|
||||
fn from(value: trap::Label<PathExpr>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExpr is a subclass of Expr
|
||||
impl From<trap::Label<PathExprBase>> for trap::Label<Expr> {
|
||||
fn from(value: trap::Label<PathExprBase>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExprBase is a subclass of Expr
|
||||
unsafe {
|
||||
Self::from_untyped(value.as_untyped())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<trap::Label<PathExpr>> for trap::Label<Locatable> {
|
||||
fn from(value: trap::Label<PathExpr>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExpr is a subclass of Locatable
|
||||
impl From<trap::Label<PathExprBase>> for trap::Label<Locatable> {
|
||||
fn from(value: trap::Label<PathExprBase>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExprBase is a subclass of Locatable
|
||||
unsafe {
|
||||
Self::from_untyped(value.as_untyped())
|
||||
}
|
||||
@@ -9225,6 +9207,78 @@ impl From<trap::Label<Module>> for trap::Label<Stmt> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PathExpr {
|
||||
pub id: trap::TrapId<PathExpr>,
|
||||
pub attrs: Vec<trap::Label<Attr>>,
|
||||
pub path: Option<trap::Label<Path>>,
|
||||
}
|
||||
|
||||
impl trap::TrapEntry for PathExpr {
|
||||
fn extract_id(&mut self) -> trap::TrapId<Self> {
|
||||
std::mem::replace(&mut self.id, trap::TrapId::Star)
|
||||
}
|
||||
|
||||
fn emit(self, id: trap::Label<Self>, out: &mut trap::Writer) {
|
||||
out.add_tuple("path_exprs", vec![id.into()]);
|
||||
for (i, v) in self.attrs.into_iter().enumerate() {
|
||||
out.add_tuple("path_expr_attrs", vec![id.into(), i.into(), v.into()]);
|
||||
}
|
||||
if let Some(v) = self.path {
|
||||
out.add_tuple("path_expr_paths", vec![id.into(), v.into()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl trap::TrapClass for PathExpr {
|
||||
fn class_name() -> &'static str { "PathExpr" }
|
||||
}
|
||||
|
||||
impl From<trap::Label<PathExpr>> for trap::Label<AstNode> {
|
||||
fn from(value: trap::Label<PathExpr>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExpr is a subclass of AstNode
|
||||
unsafe {
|
||||
Self::from_untyped(value.as_untyped())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<trap::Label<PathExpr>> for trap::Label<Element> {
|
||||
fn from(value: trap::Label<PathExpr>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExpr is a subclass of Element
|
||||
unsafe {
|
||||
Self::from_untyped(value.as_untyped())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<trap::Label<PathExpr>> for trap::Label<Expr> {
|
||||
fn from(value: trap::Label<PathExpr>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExpr is a subclass of Expr
|
||||
unsafe {
|
||||
Self::from_untyped(value.as_untyped())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<trap::Label<PathExpr>> for trap::Label<Locatable> {
|
||||
fn from(value: trap::Label<PathExpr>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExpr is a subclass of Locatable
|
||||
unsafe {
|
||||
Self::from_untyped(value.as_untyped())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<trap::Label<PathExpr>> for trap::Label<PathExprBase> {
|
||||
fn from(value: trap::Label<PathExpr>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme PathExpr is a subclass of PathExprBase
|
||||
unsafe {
|
||||
Self::from_untyped(value.as_untyped())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Static {
|
||||
pub id: trap::TrapId<Static>,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use itertools::Itertools;
|
||||
use log::info;
|
||||
use log::{debug, info};
|
||||
use ra_ap_base_db::SourceDatabase;
|
||||
use ra_ap_base_db::SourceDatabaseFileInputExt;
|
||||
use ra_ap_hir::Semantics;
|
||||
@@ -119,10 +119,21 @@ pub fn find_project_manifests(
|
||||
.map(|path| AbsPathBuf::assert_utf8(current.join(path)))
|
||||
.collect();
|
||||
let ret = ra_ap_project_model::ProjectManifest::discover_all(&abs_files);
|
||||
info!(
|
||||
"found manifests: {}",
|
||||
ret.iter().map(|m| format!("{m}")).join(", ")
|
||||
);
|
||||
let iter = || ret.iter().map(|m| format!(" {m}"));
|
||||
const LOG_LIMIT: usize = 10;
|
||||
if ret.len() <= LOG_LIMIT {
|
||||
info!("found manifests:\n{}", iter().join("\n"));
|
||||
} else {
|
||||
info!(
|
||||
"found manifests:\n{}\nand {} more",
|
||||
iter().take(LOG_LIMIT).join("\n"),
|
||||
ret.len() - LOG_LIMIT
|
||||
);
|
||||
debug!(
|
||||
"rest of the manifests found:\n{}",
|
||||
iter().dropping(LOG_LIMIT).join("\n")
|
||||
);
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
fn from_utf8_lossy(v: &[u8]) -> (Cow<'_, str>, Option<SyntaxError>) {
|
||||
|
||||
@@ -142,7 +142,7 @@ impl<'a> Translator<'a> {
|
||||
self.trap.emit_location(self.label, label, start, end)
|
||||
} else {
|
||||
self.emit_diagnostic(
|
||||
DiagnosticSeverity::Info,
|
||||
DiagnosticSeverity::Debug,
|
||||
"locations".to_owned(),
|
||||
"missing location for AstNode".to_owned(),
|
||||
"missing location for AstNode".to_owned(),
|
||||
@@ -169,9 +169,9 @@ impl<'a> Translator<'a> {
|
||||
pub fn emit_diagnostic(
|
||||
&mut self,
|
||||
severity: DiagnosticSeverity,
|
||||
error_tag: String,
|
||||
error_message: String,
|
||||
full_error_message: String,
|
||||
tag: String,
|
||||
message: String,
|
||||
full_message: String,
|
||||
location: (LineCol, LineCol),
|
||||
) {
|
||||
let (start, end) = location;
|
||||
@@ -187,16 +187,13 @@ impl<'a> Translator<'a> {
|
||||
self.path,
|
||||
start.line + 1,
|
||||
start.col + 1,
|
||||
&error_message
|
||||
);
|
||||
let location = self.trap.emit_location_label(self.label, start, end);
|
||||
self.trap.emit_diagnostic(
|
||||
severity,
|
||||
error_tag,
|
||||
error_message,
|
||||
full_error_message,
|
||||
location,
|
||||
&message
|
||||
);
|
||||
if severity > DiagnosticSeverity::Debug {
|
||||
let location = self.trap.emit_location_label(self.label, start, end);
|
||||
self.trap
|
||||
.emit_diagnostic(severity, tag, message, full_message, location);
|
||||
}
|
||||
}
|
||||
pub fn emit_parse_error(&mut self, owner: &impl ast::AstNode, err: &SyntaxError) {
|
||||
let owner_range: TextRange = owner.syntax().text_range();
|
||||
|
||||
@@ -128,7 +128,7 @@ pub struct TrapFile {
|
||||
compression: Compression,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum DiagnosticSeverity {
|
||||
Debug = 10,
|
||||
Info = 20,
|
||||
|
||||
26
rust/ql/.generated.list
generated
26
rust/ql/.generated.list
generated
@@ -40,8 +40,11 @@ lib/codeql/rust/elements/FieldList.qll bd243adc4696c60f636055a1c2da28039fe202847
|
||||
lib/codeql/rust/elements/FnPtrType.qll c4a90dc660cf620972dc23b95494f5caf9f050eabd4bdb52fdc061f8797ba9a1 f8defc91582fa503607664668f9e2e6c2cd8b320c7c449610f21e52e332a129f
|
||||
lib/codeql/rust/elements/ForExpr.qll 312804d53dd9236a2f2a15c9d6ec348b46e139a54eb5893e7e12487725df7444 fa5e20099b1179033bc209bad3548e3d1d4019c7fe0e455cec8ca1a9d48692ab
|
||||
lib/codeql/rust/elements/ForType.qll 0036bed8749358c356d78c4a0eef40d73e2796284293cde5604ae70ddd6d0470 4edcaf8f7c67d42ebe3ebb1be6a7643758717d4fe88f5f648b6a1c5ff4ee4de7
|
||||
lib/codeql/rust/elements/Format.qll 506172d176f4b965f428585c032464f4abe07a0e47c574f8e011d8641ec45370 653e81bf233b8729649064de64f4a7a8533f8864ac6d2ea913f347088c924c60
|
||||
lib/codeql/rust/elements/FormatArgsArg.qll 5bc9b4cd1bac7131165836e93838c45452a08ea6011741cbddace3cbf9c69440 f825140e98dc9800d5c045402186793c7b21511448e2f6bf6402d1e06305219c
|
||||
lib/codeql/rust/elements/FormatArgsExpr.qll f2ffad5a1105b29a8437c8ed6cf918cfcf4d65ac164bbf1be0585c3b673ca749 3ba20dc312a0a994bb43b37b2db72cbd4e06061b97918fa0e84ce355070ffbeb
|
||||
lib/codeql/rust/elements/FormatArgument.qll bdd93e1da78637f19beee6f953d3a45512100e925d90cb5ad08a097f412009b8 2a0ae7eb885615e380f925c0d130a1b795bf3c395486550a1f1c9c82848f8d77
|
||||
lib/codeql/rust/elements/FormatTemplateVariableAccess.qll ff3218a1dda30c232d0ecd9d1c60bbb9f3973456ef0bee1d1a12ad14b1e082b5 e4316291c939800d8b34d477d92be9404a30d52b7eee37302aef3d3205cf4ae0
|
||||
lib/codeql/rust/elements/Function.qll 2c76c2c7036891996b1f0ebde16c414edf37ebb44ff9c3483088dc6218733e07 d84d017d98aa240bf3bee6502a030aa8cfb7ed95425ffa9853e73b41485e1f4a
|
||||
lib/codeql/rust/elements/GenericArg.qll 5f11ce0e3c5f08de84db61f56ba1b984652455ba6b95a8b8a5b5a235913d4072 756b6a73d66fde45bdcc65ce2362a5b1391af2927e6d54b6550b3ecd5fd11e75
|
||||
lib/codeql/rust/elements/GenericArgList.qll dcf274db517b0e8f19e4545d77f86cdd4066ff2805e68c808d0bb5750b49f569 1055a82929e850264e501b367ef4d314a3e6bb8943ec95f4284d157fb4d0092f
|
||||
@@ -94,7 +97,8 @@ lib/codeql/rust/elements/ParenPat.qll 40d033de6c85ad042223e0da80479adebab3549439
|
||||
lib/codeql/rust/elements/ParenType.qll e1f5695b143c97b98ccdb460a5cf872461cfc13b83a4f005f26c288dc0afae10 1164f8efae7f255925411bddb33939fab0bf1c07955a16fef173b3f4675d09ae
|
||||
lib/codeql/rust/elements/Pat.qll 56211c5cb4709e7c12a2bfd2da5e413a451672d99e23a8386c08ad0b999fd45c b1b1893a13a75c4f0390f7e2a14ee98a46f067cfdc991a8d43adc82497d20aff
|
||||
lib/codeql/rust/elements/Path.qll 0655adfe84b08c286022a0307511a781bc1bfc943c12bc50600ebffb9d00e4b0 48e55afee9d019b7c62bfb02110c626c570ecbf683258cf23786807966f0b6fc
|
||||
lib/codeql/rust/elements/PathExpr.qll 99aa8af9deb9e276eb262b1fbd1a19f1c816cafac605aedb173ecb245c3c3cbd 306c837388ba60a5a89d2a546453527c62006696e15c043ed04d1ba27345815b
|
||||
lib/codeql/rust/elements/PathExpr.qll 906df1d80c662b79f1b0b0428c39754b7f8dbcb2234919dd45dd8206a099dd36 1d6015afab6378c926c5838c9a5772cfcfeedf474e2eeca3e46085300ff8d4e1
|
||||
lib/codeql/rust/elements/PathExprBase.qll bb41092ec690ae926e3233c215dcaf1fd8e161b8a6955151949f492e02dba13a b2257072f8062d31c29c63ee1311b07e0d2eb37075f582cfc76bb542ef773198
|
||||
lib/codeql/rust/elements/PathPat.qll 6897e69bcb24b56d39ede796cf5767988dcd5741e02333fa8495dd7c814f771a 2a011fb92f17e4b4ff713e6d29f591054dfede22a9aaa006e67fca2c23ab76bf
|
||||
lib/codeql/rust/elements/PathSegment.qll 536a8fe172db367e5f1dc678a014e2350eadfc379242d2b5451725e826ab1448 1a3a237f56c1d9ccdce6832ec6417fed25cd3e29ba836363cc6085e2125de4c5
|
||||
lib/codeql/rust/elements/PathType.qll a7bd3b05dc2c0e96c91c5485db508a1f5bb8fe3a01486be6815ae9dabb163add b11e996b6c0cc21a3d8d1ddc23c37e4d54a78e84a9278b3ceca1e94cb7321532
|
||||
@@ -232,7 +236,6 @@ lib/codeql/rust/elements/internal/ForTypeImpl.qll b515639844778d0fbe51e6161a2ec1
|
||||
lib/codeql/rust/elements/internal/FormatArgsArgConstructor.qll 8bd9b4e035ef8adeb3ac510dd68043934c0140facb933be1f240096d01cdfa11 74e9d3bbd8882ae59a7e88935d468e0a90a6529a4e2af6a3d83e93944470f0ee
|
||||
lib/codeql/rust/elements/internal/FormatArgsArgImpl.qll 601f7715e9a65bcfa7cea1979fa30d694b5bea29650d799d7dd3080b8eea58e9 ecb0800cdb8c0f93277982dad295ac6a5332e42eff4fb5c8ff19f903b9857003
|
||||
lib/codeql/rust/elements/internal/FormatArgsExprConstructor.qll ce29ff5a839b885b1ab7a02d6a381ae474ab1be3e6ee7dcfd7595bdf28e4b558 63bf957426871905a51ea319662a59e38104c197a1024360aca364dc145b11e8
|
||||
lib/codeql/rust/elements/internal/FormatArgsExprImpl.qll bdb992ebc6be59311b486f40325b39f52a69921cfc66a731085cb184da00050f 6336e7770f9cb700f1b3914fd940c3423ab4e971b34ed8fcc79da80c1f1cdba3
|
||||
lib/codeql/rust/elements/internal/FunctionConstructor.qll b50aea579938d03745dfbd8b5fa8498f7f83b967369f63d6875510e09ab7f5d2 19cca32aeaecaf9debc27329e8c39ecec69464bb1d89d7b09908a1d73a8d92a2
|
||||
lib/codeql/rust/elements/internal/GenericArgImpl.qll 6b1b804c357425c223f926e560a688e81506f5a35b95485cecf704e88cc009ee cc1ccf6a23dadc397e82664f3911d4b385d4c8ca80b1ee16d5275d9c936148dd
|
||||
lib/codeql/rust/elements/internal/GenericArgListConstructor.qll 46859bb3eb09d77987a18642d65ba2e13471a4dc9c0a83a192fddc82e37c335c 2c7d54c876269a88d3461b05745e73b06532b1616cae9b614ac94b28735d8fc4
|
||||
@@ -325,6 +328,7 @@ lib/codeql/rust/elements/internal/ParenTypeConstructor.qll d62e656a4a3c8ffd4eb87
|
||||
lib/codeql/rust/elements/internal/ParenTypeImpl.qll 6f7b4fade4ac0af69bf9766ee7d73da3da1742ba8a7c12d2a067b71c7f96d849 f065ea466111a5abca33d97b9878ef2fcc221f286fc65bec87f3a9c2fd5d57fc
|
||||
lib/codeql/rust/elements/internal/PatImpl.qll 37c9b1da7aa625117644e2cd74ec0b174f69a38cf66926add01786a05d5ad2ad 143685a0b4873fa0b73b204285dca956e59b32d527bfac6cc336326d244994b7
|
||||
lib/codeql/rust/elements/internal/PathConstructor.qll 5c6354c28faf9f28f3efee8e19bdb82773adcf4b0c1a38788b06af25bcb6bc4a 3e2aeef7b6b9cda7f7f45a6c8119c98803aa644cf6a492cf0fce318eba40fe8f
|
||||
lib/codeql/rust/elements/internal/PathExprBaseImpl.qll e8b09447ee41b4123f7d94c6b366b2602d8022c9644f1088c670c7794307ab2e 96b9b328771aaf19ba18d0591e85fcc915c0f930b2479b433de3bfdd2ea25249
|
||||
lib/codeql/rust/elements/internal/PathExprConstructor.qll cf6e0a338a8ed2d1042bdee4c2c49be5827e8c572d8c56e828db265d39e59ae3 36a3d1b7c5cc2cf527616be787b32071b9e2a6613a4f6b3f82e2a3b0e02a516f
|
||||
lib/codeql/rust/elements/internal/PathExprImpl.qll 01ad25aa940bf949056db86220362f0f5a1b03a772af6a2f6aff8854170c5e49 a0f5ff6b04e2f9f22bda78bb2a7352d890899ba16cb7f6a267af902a3650c5ed
|
||||
lib/codeql/rust/elements/internal/PathImpl.qll 67ccef5792c0d17d800b910cbda3651aaa5c0ba8daa64e1fea23a1518b562193 6a54b958f7206c43565889a273a64b95aa4b915044a986ffffe7cfb4b8f9c3a9
|
||||
@@ -493,8 +497,11 @@ lib/codeql/rust/elements/internal/generated/FieldList.qll 43c13c6e3c9ba75a7a4cb8
|
||||
lib/codeql/rust/elements/internal/generated/FnPtrType.qll 748d766dbefd19a7d644734c57885eeede66897029bbfe1b87919517f43bfde2 5a7d80acc00e56594ed85026a8ea4923104d2e98c2e42db8c5bcd32ddd164e48
|
||||
lib/codeql/rust/elements/internal/generated/ForExpr.qll 541b62b48911d4999f9ed64ab6c8b9910073ac4add0225761f319677328cf120 976c3a91c9eedfb1e2d9ea76ac501348643b3d23c723d7a777042258d416d091
|
||||
lib/codeql/rust/elements/internal/generated/ForType.qll 3d43d044a1189281f09c55caafb6c8020a836f49e2866077086101925a573cf2 646b59bfd1b428aaf7211f574c49f79cb4c6a79ca151aa0663b2b31480298721
|
||||
lib/codeql/rust/elements/internal/generated/Format.qll 37ad20cf2bf363b4027a8913d095292c8a4eb8ccdf2a9965f2fb7d41930f9bfe 329b89cdd75ce951269273dd18897e32ff5cfcc94f451001c64143386c1e48dd
|
||||
lib/codeql/rust/elements/internal/generated/FormatArgsArg.qll e07a1ae310f590003f1b88fada7dcf4847c99adb9d4c838d1c88e66e1da85c5f 0ef7342451fe2cb06e765fb4b33bb8c4a9b927f5edbc8feb5c6ba3655697f447
|
||||
lib/codeql/rust/elements/internal/generated/FormatArgsExpr.qll 40d6daa7d2bafb33798a21d79774dc802cfbd7a31618ac3bd0149399ea2bf893 d1172e2151791228559004792e125fc4625f6a26ffad25f29efb0ad263bf8795
|
||||
lib/codeql/rust/elements/internal/generated/FormatArgument.qll 00646f38217a66978b8b2648cca39dddbed22ece693b26cb682f019fbfedda95 e364e085f967847a7ed21b76156a9203d64032f0f0eea357b4779885a41bf9a7
|
||||
lib/codeql/rust/elements/internal/generated/FormatTemplateVariableAccess.qll a6175214fad445df9234b3ee9bf5147da75baf82473fb8d384b455e3add0dac1 a928db0ff126b2e54a18f5c488232abd1bd6c5eda24591d3c3bb80c6ee71c770
|
||||
lib/codeql/rust/elements/internal/generated/Function.qll f285ee0c771f897eba6db34a7e98f3cfb7db91b0df252ff4b37fc9d779de0bfb 07401e832565ff376acda219514c2e2bbe4ae5058c76a73b40ca6ca66f1626c7
|
||||
lib/codeql/rust/elements/internal/generated/GenericArg.qll 464da0ba1c5ddcd1be68617167f177773d99b5ac4775ec8ea24d503e789a9099 6faa1033d59baf7c210ac4837a55781cfc054b7acbad8027faf4630dbfa6e101
|
||||
lib/codeql/rust/elements/internal/generated/GenericArgList.qll b8cd936bba6f28344e28c98acf38acb8ef43af6ecf8367d79ed487e5b9da17cb 8b14331261e49d004807285b02fca190aafd62bfb9378b05c7d9c1e95525fe7b
|
||||
@@ -545,19 +552,20 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b
|
||||
lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60
|
||||
lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6
|
||||
lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273
|
||||
lib/codeql/rust/elements/internal/generated/ParentChild.qll 823b35d9802fab617be5c76327d65a3e52abd4be72bbc36d93e673cea7a9baaf 9d58eb407d0a929aefc0f4d532ef39dded81f6a370b6735ef581709c82ff9bc6
|
||||
lib/codeql/rust/elements/internal/generated/ParentChild.qll 611eff5fe700323eba2dbee6f9495952059e77c3ec12038c9d45d2cdaa57efd5 f317538e9919e39dfbf3825a96231f8023568f2d4c61d814c4cebaaf8335f94c
|
||||
lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4
|
||||
lib/codeql/rust/elements/internal/generated/Path.qll 299abce24762a5ab023f3cf1ab9718b83047e171aed42a8092e7a155914b1657 db1a23d18640c548f08c9f94823838b5e019ac85877c7b15df2d1493d1846572
|
||||
lib/codeql/rust/elements/internal/generated/PathExpr.qll 17cdb0a7393258a207450f08e37178fc9d35d167f064ba6015be94246f3dc933 a75fdd280aff6d87e083a92030e041c2eb52b57cf7151d4a6989fcd31d6a64bf
|
||||
lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140
|
||||
lib/codeql/rust/elements/internal/generated/PathExprBase.qll d8218e201b8557fa6d9ca2c30b764e5ad9a04a2e4fb695cc7219bbd7636a6ac2 4ef178426d7095a156f4f8c459b4d16f63abc64336cb50a6cf883a5f7ee09113
|
||||
lib/codeql/rust/elements/internal/generated/PathPat.qll 98c9938d6a359fd717829b196eb09701d2c798e18c1f43fa7b2a9145afdf6c19 caba2e629cae08682baac90a76ae9a48cda2d7d6f9c23d506fa0ff3f292978a4
|
||||
lib/codeql/rust/elements/internal/generated/PathSegment.qll 4621597fd86246f788b8f9ca73f6b0f27929fc04261ce3ccf85da1183071431d aadda8bce386a3b7a9c53b98465eedcc4f724e37b8a904c1775af5b7ffb041ee
|
||||
lib/codeql/rust/elements/internal/generated/PathType.qll 45de78e5374d6eb0446e2112ec72d3692c2811df9fa2ad03d0127e426940abe3 622cf70408413a565a0dac58f451035ac1339c8d0ee5b24f630680201cb0aa48
|
||||
lib/codeql/rust/elements/internal/generated/PrefixExpr.qll c9ede5f2deb7b41bc8240969e8554f645057018fe96e7e9ad9c2924c8b14722b 5ae2e3c3dc8fa73e7026ef6534185afa6b0b5051804435d8b741dd3640c864e1
|
||||
lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd777c9e2bef90a0711fb8d7c2c2cec764c003ac4a cf8297d93557356a572223d3e8acca701837c4b1f54e8d4351ba195fb7ed27f8
|
||||
lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll dc03515d678ba052c2ff2dd9f0883e0bce54cac740ba9a15e5173f292c1b6971 dc03515d678ba052c2ff2dd9f0883e0bce54cac740ba9a15e5173f292c1b6971
|
||||
lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590
|
||||
lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9
|
||||
lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b
|
||||
lib/codeql/rust/elements/internal/generated/Raw.qll 429057964308876b8186a0ca901634273d91b783e4bb85aa5e47860010f4da0b feb8231d0b724fedb1d9d2a65d4a8759ae58baec902b44e3bebdb81a7fbc1fd1
|
||||
lib/codeql/rust/elements/internal/generated/Raw.qll 6ce0e8a0d2922b2484d48108ffafb1daf6312103e3b8b190774a7a6f12c73ab3 e90268b1865f7e9a671f8bcff3812bf9c0b75baf573a031395747269dfe054c8
|
||||
lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40
|
||||
lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1
|
||||
lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0
|
||||
@@ -582,8 +590,8 @@ lib/codeql/rust/elements/internal/generated/Static.qll 5fbd6879858cf356d4bdaa6da
|
||||
lib/codeql/rust/elements/internal/generated/Stmt.qll 8473ff532dd5cc9d7decaddcd174b94d610f6ca0aec8e473cc051dad9f3db917 6ef7d2b5237c2dbdcacbf7d8b39109d4dc100229f2b28b5c9e3e4fbf673ba72b
|
||||
lib/codeql/rust/elements/internal/generated/StmtList.qll a667193e32341e17400867c6e359878c4e645ef9f5f4d97676afc0283a33a026 a320ed678ee359302e2fc1b70a9476705cd616fcfa44a499d32f0c7715627f73
|
||||
lib/codeql/rust/elements/internal/generated/Struct.qll 4d57f0db12dc7ad3e31e750a24172ef1505406b4dab16386af0674bd18bf8f4b 1a73c83df926b996f629316f74c61ea775be04532ab61b56af904223354f033e
|
||||
lib/codeql/rust/elements/internal/generated/Synth.qll dd9d72a46cf446af025cd7b0085f3780ee7bf7d09a458d3ae6f495e999d342c8 cda06e3155f1a3eecc5ee8ec8097d5362234b44f815aff9bc3940860435262b3
|
||||
lib/codeql/rust/elements/internal/generated/SynthConstructors.qll 5d30b6d4f36791637f250734ee38820102c64f196454e20f79e30097da1a8e20 5d30b6d4f36791637f250734ee38820102c64f196454e20f79e30097da1a8e20
|
||||
lib/codeql/rust/elements/internal/generated/Synth.qll 68126fecadf402b76a30b6e916b1d1c15db1b06c48a401267bf59ac06aaa5ec3 545f3fa49591cf9a11b9bf6d9c860726db31dffe43be8c96ac3f2cac8d47c010
|
||||
lib/codeql/rust/elements/internal/generated/SynthConstructors.qll e929c49ea60810a2bbc19ad38110b8bbaf21db54dae90393b21a3459a54abf6f e929c49ea60810a2bbc19ad38110b8bbaf21db54dae90393b21a3459a54abf6f
|
||||
lib/codeql/rust/elements/internal/generated/Token.qll 77a91a25ca5669703cf3a4353b591cef4d72caa6b0b9db07bb9e005d69c848d1 2fdffc4882ed3a6ca9ac6d1fb5f1ac5a471ca703e2ffdc642885fa558d6e373b
|
||||
lib/codeql/rust/elements/internal/generated/TokenTree.qll 8577c2b097c1be2f0f7daa5acfcf146f78674a424d99563e08a84dd3e6d91b46 d2f30764e84dbfc0a6a5d3d8a5f935cd432413688cb32da9c94e420fbc10665c
|
||||
lib/codeql/rust/elements/internal/generated/Trait.qll a570fa93d0b78a35766b00d5ca256c102f824564248b9d8b678a981d6eea3e2e d9c7475e5102e21cfdee3b1791f89a4f9cdba5a4200349ff706532b704c02664
|
||||
@@ -617,7 +625,7 @@ lib/codeql/rust/elements/internal/generated/WhileExpr.qll fec8a9211b82a80601bf73
|
||||
lib/codeql/rust/elements/internal/generated/WildcardPat.qll d74b70b57a0a66bfae017a329352a5b27a6b9e73dd5521d627f680e810c6c59e 4b913b548ba27ff3c82fcd32cf996ff329cb57d176d3bebd0fcef394486ea499
|
||||
lib/codeql/rust/elements/internal/generated/YeetExpr.qll cac328200872a35337b4bcb15c851afb4743f82c080f9738d295571eb01d7392 94af734eea08129b587fed849b643e7572800e8330c0b57d727d41abda47930b
|
||||
lib/codeql/rust/elements/internal/generated/YieldExpr.qll 37e5f0c1e373a22bbc53d8b7f2c0e1f476e5be5080b8437c5e964f4e83fad79a 4a9a68643401637bf48e5c2b2f74a6bf0ddcb4ff76f6bffb61d436b685621e85
|
||||
lib/codeql/rust/elements.qll ef8063c90411cb957c776756837a4c7ad43aa4eeb52595786e8b2b96dc10ebff ef8063c90411cb957c776756837a4c7ad43aa4eeb52595786e8b2b96dc10ebff
|
||||
lib/codeql/rust/elements.qll 6dc44d60d8180da23e7df8815adafa506936c7704723df0592bd1c6c60280abe 6dc44d60d8180da23e7df8815adafa506936c7704723df0592bd1c6c60280abe
|
||||
test/extractor-tests/generated/Abi/Abi.ql 7f6e7dc4af86eca3ebdc79b10373988cd0871bd78b51997d3cffd969105e5fdd 2f936b6ca005c6157c755121584410c03e4a3949c23bee302fbe05ee10ce118f
|
||||
test/extractor-tests/generated/Abi/Abi_getAbiString.ql a496762fcec5a0887b87023bbf93e9b650f02e20113e25c44d6e4281ae8f5335 14109c7ce11ba25e3cd6e7f1b3fcb4cb00622f2a4eac91bfe43145c5f366bc52
|
||||
test/extractor-tests/generated/ArgList/ArgList.ql e412927756e72165d0e7c5c9bd3fca89d08197bbf760db8fb7683c64bb2229bc 043dba8506946fbb87753e22c387987d7eded6ddb963aa067f9e60ef9024d684
|
||||
|
||||
10
rust/ql/.gitattributes
generated
vendored
10
rust/ql/.gitattributes
generated
vendored
@@ -42,8 +42,11 @@
|
||||
/lib/codeql/rust/elements/FnPtrType.qll linguist-generated
|
||||
/lib/codeql/rust/elements/ForExpr.qll linguist-generated
|
||||
/lib/codeql/rust/elements/ForType.qll linguist-generated
|
||||
/lib/codeql/rust/elements/Format.qll linguist-generated
|
||||
/lib/codeql/rust/elements/FormatArgsArg.qll linguist-generated
|
||||
/lib/codeql/rust/elements/FormatArgsExpr.qll linguist-generated
|
||||
/lib/codeql/rust/elements/FormatArgument.qll linguist-generated
|
||||
/lib/codeql/rust/elements/FormatTemplateVariableAccess.qll linguist-generated
|
||||
/lib/codeql/rust/elements/Function.qll linguist-generated
|
||||
/lib/codeql/rust/elements/GenericArg.qll linguist-generated
|
||||
/lib/codeql/rust/elements/GenericArgList.qll linguist-generated
|
||||
@@ -97,6 +100,7 @@
|
||||
/lib/codeql/rust/elements/Pat.qll linguist-generated
|
||||
/lib/codeql/rust/elements/Path.qll linguist-generated
|
||||
/lib/codeql/rust/elements/PathExpr.qll linguist-generated
|
||||
/lib/codeql/rust/elements/PathExprBase.qll linguist-generated
|
||||
/lib/codeql/rust/elements/PathPat.qll linguist-generated
|
||||
/lib/codeql/rust/elements/PathSegment.qll linguist-generated
|
||||
/lib/codeql/rust/elements/PathType.qll linguist-generated
|
||||
@@ -234,7 +238,6 @@
|
||||
/lib/codeql/rust/elements/internal/FormatArgsArgConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/FormatArgsArgImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/FormatArgsExprConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/FormatArgsExprImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/FunctionConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/GenericArgImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/GenericArgListConstructor.qll linguist-generated
|
||||
@@ -327,6 +330,7 @@
|
||||
/lib/codeql/rust/elements/internal/ParenTypeImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/PatImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/PathConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/PathExprBaseImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/PathExprConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/PathExprImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/PathImpl.qll linguist-generated
|
||||
@@ -495,8 +499,11 @@
|
||||
/lib/codeql/rust/elements/internal/generated/FnPtrType.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/ForExpr.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/ForType.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/Format.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/FormatArgsArg.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/FormatArgsExpr.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/FormatArgument.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/FormatTemplateVariableAccess.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/Function.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/GenericArg.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/GenericArgList.qll linguist-generated
|
||||
@@ -551,6 +558,7 @@
|
||||
/lib/codeql/rust/elements/internal/generated/Pat.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/Path.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/PathExpr.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/PathExprBase.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/PathPat.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/PathSegment.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/PathType.qll linguist-generated
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
fn foo() {
|
||||
wat
|
||||
is
|
||||
this?
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where exists(f.getLocation().getFile().getRelativePath())
|
||||
select f
|
||||
@@ -0,0 +1 @@
|
||||
qltest_cargo_check: true
|
||||
1
rust/ql/integration-tests/qltest/lib/functions.expected
Normal file
1
rust/ql/integration-tests/qltest/lib/functions.expected
Normal file
@@ -0,0 +1 @@
|
||||
| test.rs:1:1:1:11 | foo |
|
||||
5
rust/ql/integration-tests/qltest/lib/functions.ql
Normal file
5
rust/ql/integration-tests/qltest/lib/functions.ql
Normal file
@@ -0,0 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where exists(f.getLocation().getFile().getRelativePath())
|
||||
select f
|
||||
1
rust/ql/integration-tests/qltest/lib/test.rs
Normal file
1
rust/ql/integration-tests/qltest/lib/test.rs
Normal file
@@ -0,0 +1 @@
|
||||
fn foo() {}
|
||||
2
rust/ql/integration-tests/qltest/main/functions.expected
Normal file
2
rust/ql/integration-tests/qltest/main/functions.expected
Normal file
@@ -0,0 +1,2 @@
|
||||
| main.rs:1:1:1:12 | main |
|
||||
| test.rs:1:1:1:11 | foo |
|
||||
5
rust/ql/integration-tests/qltest/main/functions.ql
Normal file
5
rust/ql/integration-tests/qltest/main/functions.ql
Normal file
@@ -0,0 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where exists(f.getLocation().getFile().getRelativePath())
|
||||
select f
|
||||
1
rust/ql/integration-tests/qltest/main/main.rs
Normal file
1
rust/ql/integration-tests/qltest/main/main.rs
Normal file
@@ -0,0 +1 @@
|
||||
fn main() {}
|
||||
1
rust/ql/integration-tests/qltest/main/test.rs
Normal file
1
rust/ql/integration-tests/qltest/main/test.rs
Normal file
@@ -0,0 +1 @@
|
||||
fn foo() {}
|
||||
5
rust/ql/integration-tests/qltest/qlpack.yml
Normal file
5
rust/ql/integration-tests/qltest/qlpack.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
dependencies:
|
||||
codeql/rust-queries: '*'
|
||||
codeql/rust-all: '*'
|
||||
extractor: rust
|
||||
warnOnImplicitThis: true
|
||||
17
rust/ql/integration-tests/qltest/test.py
Normal file
17
rust/ql/integration-tests/qltest/test.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import runs_on
|
||||
# these tests are meant to exercise QL test running on multiple platforms
|
||||
# therefore they don't rely on integration test built-in QL test running
|
||||
# (which skips `qltest.{sh,cmd}`)
|
||||
|
||||
def test_lib(codeql, rust, cwd):
|
||||
codeql.test.run("lib", threads=1)
|
||||
|
||||
def test_main(codeql, rust):
|
||||
codeql.test.run("main", threads=1)
|
||||
|
||||
def test_failing_cargo_check(codeql, rust):
|
||||
out = codeql.test.run("failing_cargo_check", threads=1, show_extractor_output=True,
|
||||
_assert_failure=True, _capture="stderr")
|
||||
# TODO: QL test output redirection is currently broken on windows, leaving it up for follow-up work
|
||||
if not runs_on.windows:
|
||||
assert "requested cargo check failed" in out
|
||||
@@ -1,68 +1,8 @@
|
||||
/** Provides classes for working with locations. */
|
||||
|
||||
import files.FileSystem
|
||||
private import codeql.rust.elements.internal.LocationImpl
|
||||
|
||||
/**
|
||||
* A location as given by a file, a start line, a start column,
|
||||
* an end line, and an end column.
|
||||
*
|
||||
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
class Location extends @location_default {
|
||||
/** Gets the file for this location. */
|
||||
File getFile() { locations_default(this, result, _, _, _, _) }
|
||||
final class Location = LocationImpl::Location;
|
||||
|
||||
/** Gets the 1-based line number (inclusive) where this location starts. */
|
||||
int getStartLine() { locations_default(this, _, result, _, _, _) }
|
||||
|
||||
/** Gets the 1-based column number (inclusive) where this location starts. */
|
||||
int getStartColumn() { locations_default(this, _, _, result, _, _) }
|
||||
|
||||
/** Gets the 1-based line number (inclusive) where this location ends. */
|
||||
int getEndLine() { locations_default(this, _, _, _, result, _) }
|
||||
|
||||
/** Gets the 1-based column number (inclusive) where this location ends. */
|
||||
int getEndColumn() { locations_default(this, _, _, _, _, result) }
|
||||
|
||||
/** Gets the number of lines covered by this location. */
|
||||
int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
bindingset[this]
|
||||
pragma[inline_late]
|
||||
string toString() {
|
||||
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
|
||||
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
|
||||
result = filepath + "@" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
exists(File f |
|
||||
locations_default(this, f, startline, startcolumn, endline, endcolumn) and
|
||||
filepath = f.getAbsolutePath()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if this location starts strictly before the specified location. */
|
||||
pragma[inline]
|
||||
predicate strictlyBefore(Location other) {
|
||||
this.getStartLine() < other.getStartLine()
|
||||
or
|
||||
this.getStartLine() = other.getStartLine() and this.getStartColumn() < other.getStartColumn()
|
||||
}
|
||||
}
|
||||
|
||||
/** An entity representing an empty location. */
|
||||
class EmptyLocation extends Location {
|
||||
EmptyLocation() { empty_location(this) }
|
||||
}
|
||||
final class EmptyLocation = LocationImpl::EmptyLocation;
|
||||
|
||||
@@ -20,7 +20,9 @@ query predicate multipleToStrings(Element e, string s) {
|
||||
*/
|
||||
query predicate multipleLocations(Locatable e) { strictcount(e.getLocation()) > 1 }
|
||||
|
||||
private predicate multiplePrimaryQlClasses(Element e) { strictcount(e.getAPrimaryQlClass()) > 1 }
|
||||
private predicate multiplePrimaryQlClasses(Element e) {
|
||||
strictcount(string cls | cls = e.getAPrimaryQlClass() and cls != "VariableAccess") > 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `e` has more than one `getPrimaryQlClasses()` result.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** Provides classes relating to extraction diagnostics. */
|
||||
|
||||
private import codeql.Locations
|
||||
private import codeql.rust.elements.internal.LocationImpl
|
||||
|
||||
/** A diagnostic emitted during extraction, such as a parse error */
|
||||
class Diagnostic extends @diagnostic {
|
||||
@@ -10,7 +11,12 @@ class Diagnostic extends @diagnostic {
|
||||
string fullMessage;
|
||||
Location location;
|
||||
|
||||
Diagnostic() { diagnostics(this, severity, tag, message, fullMessage, location) }
|
||||
Diagnostic() {
|
||||
exists(@location_default loc |
|
||||
diagnostics(this, severity, tag, message, fullMessage, loc) and
|
||||
location = LocationImpl::TLocationDefault(loc)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the numerical severity level associated with this diagnostic.
|
||||
|
||||
@@ -5,6 +5,7 @@ private import Scope as Scope
|
||||
private import codeql.rust.controlflow.ControlFlowGraph as Cfg
|
||||
|
||||
private module CfgInput implements InputSig<Location> {
|
||||
private import codeql.rust.internal.CachedStages
|
||||
private import rust as Rust
|
||||
private import Completion as C
|
||||
|
||||
@@ -21,7 +22,10 @@ private module CfgInput implements InputSig<Location> {
|
||||
/** An AST node with an associated control-flow graph. */
|
||||
class CfgScope = Scope::CfgScope;
|
||||
|
||||
CfgScope getCfgScope(AstNode n) { result = n.getEnclosingCallable() }
|
||||
CfgScope getCfgScope(AstNode n) {
|
||||
result = n.getEnclosingCallable() and
|
||||
Stages::CfgStage::ref()
|
||||
}
|
||||
|
||||
class SuccessorType = Cfg::SuccessorType;
|
||||
|
||||
@@ -89,6 +93,31 @@ class ParamTree extends StandardPostOrderTree, Param {
|
||||
override AstNode getChildNode(int i) { i = 0 and result = this.getPat() }
|
||||
}
|
||||
|
||||
class FormatArgsExprTree extends StandardPostOrderTree, FormatArgsExpr {
|
||||
override AstNode getChildNode(int i) {
|
||||
i = -1 and result = this.getTemplate()
|
||||
or
|
||||
result = this.getArg(i).getExpr()
|
||||
or
|
||||
result =
|
||||
any(FormatTemplateVariableAccess v, Format f, int index, int kind |
|
||||
f = this.getFormat(index) and
|
||||
(
|
||||
v.getArgument() = f.getArgumentRef() and kind = 0
|
||||
or
|
||||
v.getArgument() = f.getWidthArgument() and kind = 1
|
||||
or
|
||||
v.getArgument() = f.getPrecisionArgument() and kind = 2
|
||||
) and
|
||||
i = this.getNumberOfArgs() + index * 3 + kind
|
||||
|
|
||||
v
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class FormatTemplateVariableAccessTree extends LeafTree, FormatTemplateVariableAccess { }
|
||||
|
||||
class ItemTree extends LeafTree, Item {
|
||||
ItemTree() {
|
||||
not this instanceof MacroCall and
|
||||
|
||||
@@ -4,8 +4,10 @@ private import Scope
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
private import codeql.rust.internal.CachedStages
|
||||
|
||||
cached
|
||||
newtype TSplitKind = TConditionalCompletionSplitKind()
|
||||
newtype TSplitKind = TConditionalCompletionSplitKind() { Stages::CfgStage::ref() }
|
||||
|
||||
cached
|
||||
newtype TSplit = TConditionalCompletionSplit(ConditionalCompletion c)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
private import rust
|
||||
private import codeql.util.Boolean
|
||||
private import Completion
|
||||
private import codeql.rust.internal.CachedStages
|
||||
|
||||
cached
|
||||
newtype TSuccessorType =
|
||||
TSuccessorSuccessor() or
|
||||
TNormalSuccessor() { Stages::CfgStage::ref() } or
|
||||
TBooleanSuccessor(Boolean b) or
|
||||
TMatchSuccessor(Boolean b) or
|
||||
TBreakSuccessor() or
|
||||
@@ -18,7 +19,7 @@ abstract class SuccessorTypeImpl extends TSuccessorType {
|
||||
}
|
||||
|
||||
/** A normal control flow successor. */
|
||||
class NormalSuccessorImpl extends SuccessorTypeImpl, TSuccessorSuccessor {
|
||||
class NormalSuccessorImpl extends SuccessorTypeImpl, TNormalSuccessor {
|
||||
override string toString() { result = "successor" }
|
||||
}
|
||||
|
||||
|
||||
4
rust/ql/lib/codeql/rust/elements.qll
generated
4
rust/ql/lib/codeql/rust/elements.qll
generated
@@ -45,8 +45,11 @@ import codeql.rust.elements.FieldList
|
||||
import codeql.rust.elements.FnPtrType
|
||||
import codeql.rust.elements.ForExpr
|
||||
import codeql.rust.elements.ForType
|
||||
import codeql.rust.elements.Format
|
||||
import codeql.rust.elements.FormatArgsArg
|
||||
import codeql.rust.elements.FormatArgsExpr
|
||||
import codeql.rust.elements.FormatArgument
|
||||
import codeql.rust.elements.FormatTemplateVariableAccess
|
||||
import codeql.rust.elements.Function
|
||||
import codeql.rust.elements.GenericArg
|
||||
import codeql.rust.elements.GenericArgList
|
||||
@@ -100,6 +103,7 @@ import codeql.rust.elements.ParenType
|
||||
import codeql.rust.elements.Pat
|
||||
import codeql.rust.elements.Path
|
||||
import codeql.rust.elements.PathExpr
|
||||
import codeql.rust.elements.PathExprBase
|
||||
import codeql.rust.elements.PathPat
|
||||
import codeql.rust.elements.PathSegment
|
||||
import codeql.rust.elements.PathType
|
||||
|
||||
16
rust/ql/lib/codeql/rust/elements/Format.qll
generated
Normal file
16
rust/ql/lib/codeql/rust/elements/Format.qll
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
// generated by codegen, do not edit
|
||||
/**
|
||||
* This module provides the public class `Format`.
|
||||
*/
|
||||
|
||||
private import internal.FormatImpl
|
||||
import codeql.rust.elements.FormatArgsExpr
|
||||
import codeql.rust.elements.Locatable
|
||||
|
||||
/**
|
||||
* A format element in a formatting template. For example the `{}` in:
|
||||
* ```rust
|
||||
* println!("Hello {}", "world");
|
||||
* ```
|
||||
*/
|
||||
final class Format = Impl::Format;
|
||||
20
rust/ql/lib/codeql/rust/elements/FormatArgument.qll
generated
Normal file
20
rust/ql/lib/codeql/rust/elements/FormatArgument.qll
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
// generated by codegen, do not edit
|
||||
/**
|
||||
* This module provides the public class `FormatArgument`.
|
||||
*/
|
||||
|
||||
private import internal.FormatArgumentImpl
|
||||
import codeql.rust.elements.Format
|
||||
import codeql.rust.elements.Locatable
|
||||
|
||||
/**
|
||||
* An argument in a format element in a formatting template. For example the `width`, `precision`, and `value` in:
|
||||
* ```rust
|
||||
* println!("Value {value:#width$.precision$}");
|
||||
* ```
|
||||
* or the `0`, `1` and `2` in:
|
||||
* ```rust
|
||||
* println!("Value {0:#1$.2$}", value, width, precision);
|
||||
* ```
|
||||
*/
|
||||
final class FormatArgument = Impl::FormatArgument;
|
||||
9
rust/ql/lib/codeql/rust/elements/FormatTemplateVariableAccess.qll
generated
Normal file
9
rust/ql/lib/codeql/rust/elements/FormatTemplateVariableAccess.qll
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
// generated by codegen, do not edit
|
||||
/**
|
||||
* This module provides the public class `FormatTemplateVariableAccess`.
|
||||
*/
|
||||
|
||||
private import internal.FormatTemplateVariableAccessImpl
|
||||
import codeql.rust.elements.PathExprBase
|
||||
|
||||
final class FormatTemplateVariableAccess = Impl::FormatTemplateVariableAccess;
|
||||
7
rust/ql/lib/codeql/rust/elements/NamedFormatArgument.qll
Normal file
7
rust/ql/lib/codeql/rust/elements/NamedFormatArgument.qll
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* This module provides the public class `NamedFormatArgument`.
|
||||
*/
|
||||
|
||||
private import internal.FormatArgumentImpl
|
||||
|
||||
final class NamedFormatArgument = Impl::NamedFormatArgument;
|
||||
2
rust/ql/lib/codeql/rust/elements/PathExpr.qll
generated
2
rust/ql/lib/codeql/rust/elements/PathExpr.qll
generated
@@ -5,8 +5,8 @@
|
||||
|
||||
private import internal.PathExprImpl
|
||||
import codeql.rust.elements.Attr
|
||||
import codeql.rust.elements.Expr
|
||||
import codeql.rust.elements.Path
|
||||
import codeql.rust.elements.PathExprBase
|
||||
|
||||
/**
|
||||
* A path expression. For example:
|
||||
|
||||
12
rust/ql/lib/codeql/rust/elements/PathExprBase.qll
generated
Normal file
12
rust/ql/lib/codeql/rust/elements/PathExprBase.qll
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
// generated by codegen, do not edit
|
||||
/**
|
||||
* This module provides the public class `PathExprBase`.
|
||||
*/
|
||||
|
||||
private import internal.PathExprBaseImpl
|
||||
import codeql.rust.elements.Expr
|
||||
|
||||
/**
|
||||
* A path expression or a variable access in a formatting template. See `PathExpr` and `FormatTemplateVariableAccess` for further details.
|
||||
*/
|
||||
final class PathExprBase = Impl::PathExprBase;
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* This module provides the public class `PositionalFormatArgument`.
|
||||
*/
|
||||
|
||||
private import internal.FormatArgumentImpl
|
||||
|
||||
final class PositionalFormatArgument = Impl::PositionalFormatArgument;
|
||||
@@ -1,4 +1,3 @@
|
||||
// generated by codegen, remove this comment if you wish to edit this file
|
||||
/**
|
||||
* This module provides a hand-modifiable wrapper around the generated class `FormatArgsExpr`.
|
||||
*
|
||||
@@ -6,17 +5,27 @@
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.FormatArgsExpr
|
||||
private import codeql.rust.elements.Format
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the customizable definition of `FormatArgsExpr` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Impl {
|
||||
// the following QLdoc is generated: if you need to edit it, do it in the schema file
|
||||
/**
|
||||
* A FormatArgsExpr. For example:
|
||||
* ```rust
|
||||
* todo!()
|
||||
* ```
|
||||
*/
|
||||
class FormatArgsExpr extends Generated::FormatArgsExpr { }
|
||||
class FormatArgsExpr extends Generated::FormatArgsExpr {
|
||||
/**
|
||||
* Gets the `index`th format of this `FormatArgsExpr`'s formatting template (0-based).
|
||||
*/
|
||||
Format getFormat(int index) {
|
||||
result =
|
||||
rank[index + 1](Format f, int i | f.getParent() = this and f.getIndex() = i | f order by i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* This module defines the hook used internally to tweak the characteristic predicate of
|
||||
* `FormatArgument` synthesized instances.
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.internal.FormatConstructor
|
||||
|
||||
/**
|
||||
* The characteristic predicate of `FormatArgument` synthesized instances.
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
predicate constructFormatArgument(
|
||||
Raw::FormatArgsExpr parent, int index, int kind, string value, boolean positional, int offset
|
||||
) {
|
||||
exists(string text, int formatOffset, int group |
|
||||
group = [3, 4] and offset = formatOffset + 1 and kind = 0
|
||||
or
|
||||
group = [15, 16] and
|
||||
offset = formatOffset + min(text.indexOf(value + "$")) and
|
||||
kind = 1
|
||||
or
|
||||
group = [23, 24] and
|
||||
offset = formatOffset + max(text.indexOf(value + "$")) and
|
||||
kind = 2
|
||||
|
|
||||
text = formatElement(parent, index, formatOffset) and
|
||||
value = text.regexpCapture(formatRegex(), group) and
|
||||
if group % 2 = 1 then positional = true else positional = false
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* This module provides a hand-modifiable wrapper around the generated class `FormatArgument`.
|
||||
*
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.FormatArgument
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.internal.FormatArgumentConstructor
|
||||
private import codeql.rust.elements.internal.LocatableImpl::Impl as LocatableImpl
|
||||
private import codeql.files.FileSystem
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the customizable definition of `FormatArgument` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Impl {
|
||||
// the following QLdoc is generated: if you need to edit it, do it in the schema file
|
||||
/**
|
||||
* An argument in a format element in a formatting template. For example the `width`, `precision`, and `value` in:
|
||||
* ```rust
|
||||
* println!("Value {value:#width$.precision$}");
|
||||
* ```
|
||||
* or the `0`, `1` and `2` in:
|
||||
* ```rust
|
||||
* println!("Value {0:#1$.2$}", value, width, precision);
|
||||
* ```
|
||||
*/
|
||||
class FormatArgument extends Generated::FormatArgument {
|
||||
Raw::FormatArgsExpr parent;
|
||||
int index;
|
||||
int kind;
|
||||
string name;
|
||||
int offset;
|
||||
|
||||
FormatArgument() { this = Synth::TFormatArgument(parent, index, kind, name, _, offset) }
|
||||
|
||||
override string toString() { result = name }
|
||||
|
||||
override Format getParent() { result = Synth::TFormat(parent, index, _, _) }
|
||||
}
|
||||
|
||||
private class FormatSynthLocationImpl extends FormatArgument, LocatableImpl::SynthLocatable {
|
||||
override predicate hasSynthLocationInfo(
|
||||
File file, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
// TODO: handle locations in multi-line comments
|
||||
// TODO: handle the case where the template is from a nested macro call
|
||||
Synth::convertFormatArgsExprFromRaw(parent)
|
||||
.(FormatArgsExpr)
|
||||
.getTemplate()
|
||||
.getLocation()
|
||||
.hasLocationInfo(file.getAbsolutePath(), startline, startcolumn - offset, _, _) and
|
||||
endline = startline and
|
||||
endcolumn = startcolumn + name.length() - 1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A positional `FormatArgument`. For example `0` in
|
||||
* ```rust
|
||||
* let name = "Alice";
|
||||
* println!("{0} in wonderland", name);
|
||||
* ```
|
||||
*/
|
||||
class PositionalFormatArgument extends FormatArgument {
|
||||
PositionalFormatArgument() { this = Synth::TFormatArgument(_, _, _, _, true, _) }
|
||||
|
||||
/** Gets the index of this positional argument */
|
||||
int getIndex() { result = name.toInt() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A named `FormatArgument`. For example `name` in
|
||||
* ```rust
|
||||
* let name = "Alice";
|
||||
* println!("{name} in wonderland");
|
||||
* ```
|
||||
*/
|
||||
class NamedFormatArgument extends FormatArgument {
|
||||
NamedFormatArgument() { this = Synth::TFormatArgument(_, _, _, _, false, _) }
|
||||
|
||||
/** Gets the name of this named argument */
|
||||
string getName() { result = name }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* This module defines the hook used internally to tweak the characteristic predicate of
|
||||
* `Format` synthesized instances.
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
|
||||
/**
|
||||
* The characteristic predicate of `Format` synthesized instances.
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Match an element of a format string, either text (`Hello`) or a format placeholder (`{}`).
|
||||
*/
|
||||
predicate constructFormat(Raw::FormatArgsExpr parent, int index, string text, int offset) {
|
||||
text = formatElement(parent, index, offset) and
|
||||
text.charAt(0) = "{" and
|
||||
text.charAt(1) != "{"
|
||||
}
|
||||
|
||||
/**
|
||||
* Match an element of a format string, either text (`Hello`) or a format placeholder (`{}`).
|
||||
*/
|
||||
string formatElement(Raw::FormatArgsExpr parent, int occurrenceIndex, int occurrenceOffset) {
|
||||
result =
|
||||
parent
|
||||
.getTemplate()
|
||||
.(Raw::LiteralExpr)
|
||||
.getTextValue()
|
||||
// TODO: should also handle surrounding quotes and escaped characters
|
||||
.regexpFind(textRegex() + "|" + formatRegex(), occurrenceIndex, occurrenceOffset)
|
||||
}
|
||||
|
||||
/**
|
||||
* A regular expression for matching format elements in a formatting template. The syntax of
|
||||
* formatting templates is defined at https://doc.rust-lang.org/stable/std/fmt/#syntax . The
|
||||
* regular expression is generated from the following python code:
|
||||
*
|
||||
*
|
||||
* ```python
|
||||
* identifier = "([A-Za-z_][A-Za-z0-9_]*)"
|
||||
* integer = "([0-9]+)"
|
||||
*
|
||||
* # argument := integer | identifier
|
||||
* argument = "({integer}|{identifier})".format(integer=integer, identifier=identifier)
|
||||
*
|
||||
* # parameter := argument '$'
|
||||
* parameter = "(({argument})\\$)".format(argument=argument)
|
||||
*
|
||||
* # count := parameter | integer
|
||||
* count = "({parameter}|{integer})".format(integer=integer, parameter=parameter)
|
||||
*
|
||||
* # fill := character
|
||||
* fill = "(.)"
|
||||
*
|
||||
* # align := '<' | '^' | '>'
|
||||
* align = "([<^>])"
|
||||
*
|
||||
* # sign := '+' | '-'
|
||||
* sign = "([+-])"
|
||||
*
|
||||
* # width := count
|
||||
* width = count
|
||||
*
|
||||
* # precision := count | '*'
|
||||
* precision = "({count}|(\\*))".format(count=count)
|
||||
*
|
||||
* # type := '' | '?' | 'x?' | 'X?' | identifier
|
||||
* type = "(|\\?|x\\?|X\\?|{identifier})".format(identifier=identifier)
|
||||
*
|
||||
* # format_spec := [[fill]align][sign]['#']['0'][width]['.' precision]type
|
||||
* format_spec = "({fill}?{align})?{sign}?(#)?(0)?{width}?(\\.{precision})?{type}".format(fill=fill, align=align, sign=sign, width=width, precision=precision, type=type)
|
||||
*
|
||||
* # format := '{' [ argument ] [ ':' format_spec ] [ ws ] * '}'
|
||||
* format = "(\\{{{argument}?(:{format_spec})?\s*}\\})".format(argument=argument, format_spec=format_spec)
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
string formatRegex() {
|
||||
result =
|
||||
"(\\{(([0-9]+)|([A-Za-z_][A-Za-z0-9_]*))?(:((.)?([<^>]))?([+-])?(#)?(0)?(((([0-9]+)|([A-Za-z_][A-Za-z0-9_]*))\\$)|([0-9]+))?(\\.((((([0-9]+)|([A-Za-z_][A-Za-z0-9_]*))\\$)|([0-9]+))|(\\*)))?(|\\?|x\\?|X\\?|([A-Za-z_][A-Za-z0-9_]*)))?\\s*\\})"
|
||||
}
|
||||
|
||||
private string textRegex() { result = "([^{}]|\\{\\{|\\}\\})+" }
|
||||
90
rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll
Normal file
90
rust/ql/lib/codeql/rust/elements/internal/FormatImpl.qll
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* This module provides a hand-modifiable wrapper around the generated class `Format`.
|
||||
*
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Format
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.internal.FormatConstructor
|
||||
private import codeql.rust.elements.internal.LocatableImpl::Impl as LocatableImpl
|
||||
private import codeql.files.FileSystem
|
||||
import codeql.rust.elements.FormatArgument
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the customizable definition of `Format` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Impl {
|
||||
// the following QLdoc is generated: if you need to edit it, do it in the schema file
|
||||
/**
|
||||
* A format element in a formatting template. For example the `{}` in:
|
||||
* ```rust
|
||||
* println!("Hello {}", "world");
|
||||
* ```
|
||||
*/
|
||||
class Format extends Generated::Format {
|
||||
private Raw::FormatArgsExpr parent;
|
||||
string text;
|
||||
private int index;
|
||||
int offset;
|
||||
|
||||
Format() { this = Synth::TFormat(parent, index, text, offset) }
|
||||
|
||||
override string toString() { result = text }
|
||||
|
||||
override FormatArgsExpr getParent() { result = Synth::convertFormatArgsExprFromRaw(parent) }
|
||||
|
||||
override int getIndex() { result = index }
|
||||
|
||||
/**
|
||||
* Gets the name or position reference of this format, if any. For example `name` and `0` in:
|
||||
* ```rust
|
||||
* let name = "Alice";
|
||||
* println!("{name} in wonderland");
|
||||
* println!("{0} in wonderland", name);
|
||||
* ```
|
||||
*/
|
||||
FormatArgument getArgumentRef() {
|
||||
result.getParent() = this and result = Synth::TFormatArgument(_, _, 0, _, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name or position reference of the width parameter in this format, if any. For example `width` and `1` in:
|
||||
* ```rust
|
||||
* let width = 6;
|
||||
* println!("{:width$}", PI);
|
||||
* println!("{:1$}", PI, width);
|
||||
* ```
|
||||
*/
|
||||
FormatArgument getWidthArgument() {
|
||||
result.getParent() = this and result = Synth::TFormatArgument(_, _, 1, _, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name or position reference of the width parameter in this format, if any. For example `prec` and `1` in:
|
||||
* ```rust
|
||||
* let prec = 6;
|
||||
* println!("{:.prec$}", PI);
|
||||
* println!("{:.1$}", PI, prec);
|
||||
* ```
|
||||
*/
|
||||
FormatArgument getPrecisionArgument() {
|
||||
result.getParent() = this and result = Synth::TFormatArgument(_, _, 2, _, _, _)
|
||||
}
|
||||
}
|
||||
|
||||
private class FormatSynthLocationImpl extends Format, LocatableImpl::SynthLocatable {
|
||||
override predicate hasSynthLocationInfo(
|
||||
File file, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.getParent()
|
||||
.getTemplate()
|
||||
.getLocation()
|
||||
.hasLocationInfo(file.getAbsolutePath(), startline, startcolumn - offset, _, _) and
|
||||
endline = startline and
|
||||
endcolumn = startcolumn + text.length() - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* This module defines the hook used internally to tweak the characteristic predicate of
|
||||
* `FormatTemplateVariableAccess` synthesized instances.
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.Format
|
||||
private import codeql.rust.elements.NamedFormatArgument
|
||||
|
||||
/**
|
||||
* The characteristic predicate of `FormatTemplateVariableAccess` synthesized instances.
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
predicate constructFormatTemplateVariableAccess(Raw::FormatArgsExpr parent, int index, int kind) {
|
||||
unboundNamedFormatArgument(parent, index, kind, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* A named format argument for which no binding is found in the parent `FormatArgsExpr::getArg(_)`.
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
predicate unboundNamedFormatArgument(
|
||||
Raw::FormatArgsExpr parent, int index, int kind, NamedFormatArgument arg
|
||||
) {
|
||||
exists(Format format, string name |
|
||||
not parent.getArg(_).getName().getText() = name and
|
||||
name = arg.getName() and
|
||||
Synth::convertFormatArgsExprToRaw(format.getParent()) = parent and
|
||||
format.getIndex() = index
|
||||
|
|
||||
arg = format.getArgumentRef() and kind = 0
|
||||
or
|
||||
arg = format.getWidthArgument() and kind = 1
|
||||
or
|
||||
arg = format.getPrecisionArgument() and kind = 2
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* This module provides a hand-modifiable wrapper around the generated class `FormatTemplateVariableAccess`.
|
||||
*
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.FormatTemplateVariableAccess
|
||||
private import codeql.rust.elements.internal.FormatTemplateVariableAccessConstructor
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.Format
|
||||
private import codeql.rust.elements.NamedFormatArgument
|
||||
private import codeql.Locations
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the customizable definition of `FormatTemplateVariableAccess` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Impl {
|
||||
class FormatTemplateVariableAccess extends Generated::FormatTemplateVariableAccess {
|
||||
private NamedFormatArgument argument;
|
||||
|
||||
FormatTemplateVariableAccess() {
|
||||
exists(Raw::FormatArgsExpr parent, int index, int kind |
|
||||
this = Synth::TFormatTemplateVariableAccess(parent, index, kind) and
|
||||
unboundNamedFormatArgument(parent, index, kind, argument)
|
||||
)
|
||||
}
|
||||
|
||||
override Location getLocation() { result = argument.getLocation() }
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
/** Gets the name of the variable */
|
||||
string getName() { result = argument.getName() }
|
||||
|
||||
/** Gets the underlying `NamedFormatArgument` . */
|
||||
NamedFormatArgument getArgument() { result = argument }
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
import codeql.Locations
|
||||
private import codeql.rust.elements.internal.LocationImpl
|
||||
private import codeql.rust.elements.internal.generated.Locatable
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
@@ -14,17 +15,32 @@ private import codeql.rust.elements.internal.generated.Raw
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Impl {
|
||||
abstract class SynthLocatable extends Locatable {
|
||||
abstract predicate hasSynthLocationInfo(
|
||||
File file, int startline, int startcolumn, int endline, int endcolumn
|
||||
);
|
||||
|
||||
final override Location getLocation() {
|
||||
not locatable_locations(Synth::convertLocatableToRaw(this), _) and
|
||||
exists(File file, int beginLine, int beginColumn, int endLine, int endColumn |
|
||||
this.hasSynthLocationInfo(file, beginLine, beginColumn, endLine, endColumn)
|
||||
|
|
||||
result = LocationImpl::TLocationSynth(file, beginLine, beginColumn, endLine, endColumn)
|
||||
or
|
||||
exists(@location_default location |
|
||||
result = LocationImpl::TLocationDefault(location) and
|
||||
locations_default(location, file, beginLine, beginColumn, endLine, endColumn)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class Locatable extends Generated::Locatable {
|
||||
pragma[nomagic]
|
||||
final Location getLocation() {
|
||||
exists(Raw::Locatable raw |
|
||||
raw = Synth::convertLocatableToRaw(this) and
|
||||
(
|
||||
locatable_locations(raw, result)
|
||||
or
|
||||
not exists(Location loc | locatable_locations(raw, loc)) and
|
||||
result instanceof EmptyLocation
|
||||
)
|
||||
Location getLocation() {
|
||||
exists(@location_default location |
|
||||
result = LocationImpl::TLocationDefault(location) and
|
||||
locatable_locations(Synth::convertLocatableToRaw(this), location)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
100
rust/ql/lib/codeql/rust/elements/internal/LocationImpl.qll
Normal file
100
rust/ql/lib/codeql/rust/elements/internal/LocationImpl.qll
Normal file
@@ -0,0 +1,100 @@
|
||||
private import codeql.files.FileSystem
|
||||
private import codeql.rust.elements.internal.LocatableImpl::Impl as LocatableImpl
|
||||
private import codeql.rust.elements.Locatable
|
||||
private import codeql.rust.elements.Format
|
||||
private import codeql.rust.elements.FormatArgument
|
||||
|
||||
module LocationImpl {
|
||||
newtype TLocation =
|
||||
TLocationDefault(@location_default location) or
|
||||
TLocationSynth(File file, int beginLine, int beginColumn, int endLine, int endColumn) {
|
||||
not locations_default(_, file, beginLine, beginColumn, endLine, endColumn) and
|
||||
any(LocatableImpl::SynthLocatable l)
|
||||
.hasSynthLocationInfo(file, beginLine, beginColumn, endLine, endColumn)
|
||||
}
|
||||
|
||||
/**
|
||||
* A location as given by a file, a start line, a start column,
|
||||
* an end line, and an end column.
|
||||
*
|
||||
* For more information about locations see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
abstract class Location extends TLocation {
|
||||
/** Gets the file for this location. */
|
||||
File getFile() { this.hasLocationInfo(result.getAbsolutePath(), _, _, _, _) }
|
||||
|
||||
/** Gets the 1-based line number (inclusive) where this location starts. */
|
||||
int getStartLine() { this.hasLocationInfo(_, result, _, _, _) }
|
||||
|
||||
/** Gets the 1-based column number (inclusive) where this location starts. */
|
||||
int getStartColumn() { this.hasLocationInfo(_, _, result, _, _) }
|
||||
|
||||
/** Gets the 1-based line number (inclusive) where this location ends. */
|
||||
int getEndLine() { this.hasLocationInfo(_, _, _, result, _) }
|
||||
|
||||
/** Gets the 1-based column number (inclusive) where this location ends. */
|
||||
int getEndColumn() { this.hasLocationInfo(_, _, _, _, result) }
|
||||
|
||||
/** Gets the number of lines covered by this location. */
|
||||
int getNumLines() { result = this.getEndLine() - this.getStartLine() + 1 }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
bindingset[this]
|
||||
pragma[inline_late]
|
||||
string toString() {
|
||||
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
|
||||
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
|
||||
result = filepath + "@" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
abstract predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
);
|
||||
|
||||
/** Holds if this location starts strictly before the specified location. */
|
||||
pragma[inline]
|
||||
predicate strictlyBefore(Location other) {
|
||||
this.getStartLine() < other.getStartLine()
|
||||
or
|
||||
this.getStartLine() = other.getStartLine() and this.getStartColumn() < other.getStartColumn()
|
||||
}
|
||||
}
|
||||
|
||||
private class LocationDefault extends Location, TLocationDefault {
|
||||
@location_default self;
|
||||
|
||||
LocationDefault() { this = TLocationDefault(self) }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
exists(File f |
|
||||
locations_default(self, f, startline, startcolumn, endline, endcolumn) and
|
||||
filepath = f.getAbsolutePath()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** An entity representing an empty location. */
|
||||
class EmptyLocation extends LocationDefault {
|
||||
EmptyLocation() { empty_location(self) }
|
||||
}
|
||||
|
||||
private class LocationSynth extends Location, TLocationSynth {
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this =
|
||||
TLocationSynth(any(File f | f.getAbsolutePath() = filepath), startline, startcolumn,
|
||||
endline, endcolumn)
|
||||
}
|
||||
}
|
||||
}
|
||||
19
rust/ql/lib/codeql/rust/elements/internal/PathExprBaseImpl.qll
generated
Normal file
19
rust/ql/lib/codeql/rust/elements/internal/PathExprBaseImpl.qll
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
// generated by codegen, remove this comment if you wish to edit this file
|
||||
/**
|
||||
* This module provides a hand-modifiable wrapper around the generated class `PathExprBase`.
|
||||
*
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.PathExprBase
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the customizable definition of `PathExprBase` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Impl {
|
||||
/**
|
||||
* A path expression or a variable access in a formatting template. See `PathExpr` and `FormatTemplateVariableAccess` for further details.
|
||||
*/
|
||||
class PathExprBase extends Generated::PathExprBase { }
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
private import rust
|
||||
private import codeql.rust.elements.internal.generated.ParentChild
|
||||
private import codeql.rust.elements.internal.PathExprImpl::Impl as PathExprImpl
|
||||
private import codeql.rust.elements.internal.PathExprBaseImpl::Impl as PathExprBaseImpl
|
||||
private import codeql.rust.elements.internal.FormatTemplateVariableAccessImpl::Impl as FormatTemplateVariableAccessImpl
|
||||
private import codeql.util.DenseRank
|
||||
|
||||
module Impl {
|
||||
@@ -83,7 +84,10 @@ module Impl {
|
||||
// an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE),
|
||||
// which we don't appear to recognize yet anyway. This also assumes programmers follow the
|
||||
// naming guidelines, which they generally do, but they're not enforced.
|
||||
not name.charAt(0).isUppercase()
|
||||
not name.charAt(0).isUppercase() and
|
||||
// exclude parameters from functions without a body as these are trait method declarations
|
||||
// without implementations
|
||||
not exists(Function f | not f.hasBody() and f.getParamList().getAParam().getPat() = p)
|
||||
}
|
||||
|
||||
/** A variable. */
|
||||
@@ -138,12 +142,12 @@ module Impl {
|
||||
}
|
||||
|
||||
/** A path expression that may access a local variable. */
|
||||
private class VariableAccessCand extends PathExpr {
|
||||
private class VariableAccessCand extends PathExprBase {
|
||||
string name_;
|
||||
|
||||
VariableAccessCand() {
|
||||
exists(Path p, PathSegment ps |
|
||||
p = this.getPath() and
|
||||
p = this.(PathExpr).getPath() and
|
||||
not p.hasQualifier() and
|
||||
ps = p.getPart() and
|
||||
not ps.hasGenericArgList() and
|
||||
@@ -152,8 +156,12 @@ module Impl {
|
||||
not ps.hasReturnTypeSyntax() and
|
||||
name_ = ps.getNameRef().getText()
|
||||
)
|
||||
or
|
||||
this.(FormatTemplateVariableAccess).getName() = name_
|
||||
}
|
||||
|
||||
string toString() { result = name_ }
|
||||
|
||||
string getName() { result = name_ }
|
||||
}
|
||||
|
||||
@@ -164,7 +172,10 @@ module Impl {
|
||||
n instanceof LetStmt or
|
||||
n instanceof VariableScope
|
||||
) and
|
||||
exists(AstNode n0 | result = getImmediateParent(n0) |
|
||||
exists(AstNode n0 |
|
||||
result = getImmediateParent(n0) or
|
||||
result = n0.(FormatTemplateVariableAccess).getArgument().getParent().getParent()
|
||||
|
|
||||
n0 = n
|
||||
or
|
||||
n0 = getAnAncestorInVariableScope(n) and
|
||||
@@ -422,7 +433,7 @@ module Impl {
|
||||
}
|
||||
|
||||
/** A variable access. */
|
||||
class VariableAccess extends PathExprImpl::PathExpr instanceof VariableAccessCand {
|
||||
class VariableAccess extends PathExprBaseImpl::PathExprBase instanceof VariableAccessCand {
|
||||
private string name;
|
||||
private Variable v;
|
||||
|
||||
|
||||
38
rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll
generated
Normal file
38
rust/ql/lib/codeql/rust/elements/internal/generated/Format.qll
generated
Normal file
@@ -0,0 +1,38 @@
|
||||
// generated by codegen, do not edit
|
||||
/**
|
||||
* This module provides the generated definition of `Format`.
|
||||
* INTERNAL: Do not import directly.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
import codeql.rust.elements.FormatArgsExpr
|
||||
import codeql.rust.elements.internal.LocatableImpl::Impl as LocatableImpl
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the fully generated definition of `Format` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Generated {
|
||||
/**
|
||||
* A format element in a formatting template. For example the `{}` in:
|
||||
* ```rust
|
||||
* println!("Hello {}", "world");
|
||||
* ```
|
||||
* INTERNAL: Do not reference the `Generated::Format` class directly.
|
||||
* Use the subclass `Format`, where the following predicates are available.
|
||||
*/
|
||||
class Format extends Synth::TFormat, LocatableImpl::Locatable {
|
||||
override string getAPrimaryQlClass() { result = "Format" }
|
||||
|
||||
/**
|
||||
* Gets the parent of this format.
|
||||
*/
|
||||
FormatArgsExpr getParent() { none() }
|
||||
|
||||
/**
|
||||
* Gets the index of this format.
|
||||
*/
|
||||
int getIndex() { none() }
|
||||
}
|
||||
}
|
||||
37
rust/ql/lib/codeql/rust/elements/internal/generated/FormatArgument.qll
generated
Normal file
37
rust/ql/lib/codeql/rust/elements/internal/generated/FormatArgument.qll
generated
Normal file
@@ -0,0 +1,37 @@
|
||||
// generated by codegen, do not edit
|
||||
/**
|
||||
* This module provides the generated definition of `FormatArgument`.
|
||||
* INTERNAL: Do not import directly.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
import codeql.rust.elements.Format
|
||||
import codeql.rust.elements.internal.LocatableImpl::Impl as LocatableImpl
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the fully generated definition of `FormatArgument` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Generated {
|
||||
/**
|
||||
* An argument in a format element in a formatting template. For example the `width`, `precision`, and `value` in:
|
||||
* ```rust
|
||||
* println!("Value {value:#width$.precision$}");
|
||||
* ```
|
||||
* or the `0`, `1` and `2` in:
|
||||
* ```rust
|
||||
* println!("Value {0:#1$.2$}", value, width, precision);
|
||||
* ```
|
||||
* INTERNAL: Do not reference the `Generated::FormatArgument` class directly.
|
||||
* Use the subclass `FormatArgument`, where the following predicates are available.
|
||||
*/
|
||||
class FormatArgument extends Synth::TFormatArgument, LocatableImpl::Locatable {
|
||||
override string getAPrimaryQlClass() { result = "FormatArgument" }
|
||||
|
||||
/**
|
||||
* Gets the parent of this format argument.
|
||||
*/
|
||||
Format getParent() { none() }
|
||||
}
|
||||
}
|
||||
25
rust/ql/lib/codeql/rust/elements/internal/generated/FormatTemplateVariableAccess.qll
generated
Normal file
25
rust/ql/lib/codeql/rust/elements/internal/generated/FormatTemplateVariableAccess.qll
generated
Normal file
@@ -0,0 +1,25 @@
|
||||
// generated by codegen, do not edit
|
||||
/**
|
||||
* This module provides the generated definition of `FormatTemplateVariableAccess`.
|
||||
* INTERNAL: Do not import directly.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
import codeql.rust.elements.internal.PathExprBaseImpl::Impl as PathExprBaseImpl
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the fully generated definition of `FormatTemplateVariableAccess` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Generated {
|
||||
/**
|
||||
* INTERNAL: Do not reference the `Generated::FormatTemplateVariableAccess` class directly.
|
||||
* Use the subclass `FormatTemplateVariableAccess`, where the following predicates are available.
|
||||
*/
|
||||
class FormatTemplateVariableAccess extends Synth::TFormatTemplateVariableAccess,
|
||||
PathExprBaseImpl::PathExprBase
|
||||
{
|
||||
override string getAPrimaryQlClass() { result = "FormatTemplateVariableAccess" }
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,34 @@ private module Impl {
|
||||
)
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfFormat(Format e, int index, string partialPredicateCall) {
|
||||
exists(int b, int bLocatable, int n |
|
||||
b = 0 and
|
||||
bLocatable = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLocatable(e, i, _)) | i) and
|
||||
n = bLocatable and
|
||||
(
|
||||
none()
|
||||
or
|
||||
result = getImmediateChildOfLocatable(e, index - b, partialPredicateCall)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfFormatArgument(
|
||||
FormatArgument e, int index, string partialPredicateCall
|
||||
) {
|
||||
exists(int b, int bLocatable, int n |
|
||||
b = 0 and
|
||||
bLocatable = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfLocatable(e, i, _)) | i) and
|
||||
n = bLocatable and
|
||||
(
|
||||
none()
|
||||
or
|
||||
result = getImmediateChildOfLocatable(e, index - b, partialPredicateCall)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfMissing(Missing e, int index, string partialPredicateCall) {
|
||||
exists(int b, int bUnextracted, int n |
|
||||
b = 0 and
|
||||
@@ -2214,22 +2242,17 @@ private module Impl {
|
||||
)
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfPathExpr(PathExpr e, int index, string partialPredicateCall) {
|
||||
exists(int b, int bExpr, int n, int nAttr, int nPath |
|
||||
private Element getImmediateChildOfPathExprBase(
|
||||
PathExprBase e, int index, string partialPredicateCall
|
||||
) {
|
||||
exists(int b, int bExpr, int n |
|
||||
b = 0 and
|
||||
bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and
|
||||
n = bExpr and
|
||||
nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and
|
||||
nPath = nAttr + 1 and
|
||||
(
|
||||
none()
|
||||
or
|
||||
result = getImmediateChildOfExpr(e, index - b, partialPredicateCall)
|
||||
or
|
||||
result = e.getAttr(index - n) and
|
||||
partialPredicateCall = "Attr(" + (index - n).toString() + ")"
|
||||
or
|
||||
index = nAttr and result = e.getPath() and partialPredicateCall = "Path()"
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -2940,6 +2963,22 @@ private module Impl {
|
||||
)
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfFormatTemplateVariableAccess(
|
||||
FormatTemplateVariableAccess e, int index, string partialPredicateCall
|
||||
) {
|
||||
exists(int b, int bPathExprBase, int n |
|
||||
b = 0 and
|
||||
bPathExprBase =
|
||||
b + 1 + max(int i | i = -1 or exists(getImmediateChildOfPathExprBase(e, i, _)) | i) and
|
||||
n = bPathExprBase and
|
||||
(
|
||||
none()
|
||||
or
|
||||
result = getImmediateChildOfPathExprBase(e, index - b, partialPredicateCall)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfFunction(Function e, int index, string partialPredicateCall) {
|
||||
exists(
|
||||
int b, int bAssocItem, int bExternItem, int bItem, int bCallable, int n, int nAbi, int nBody,
|
||||
@@ -3176,6 +3215,27 @@ private module Impl {
|
||||
)
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfPathExpr(PathExpr e, int index, string partialPredicateCall) {
|
||||
exists(int b, int bPathExprBase, int n, int nAttr, int nPath |
|
||||
b = 0 and
|
||||
bPathExprBase =
|
||||
b + 1 + max(int i | i = -1 or exists(getImmediateChildOfPathExprBase(e, i, _)) | i) and
|
||||
n = bPathExprBase and
|
||||
nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and
|
||||
nPath = nAttr + 1 and
|
||||
(
|
||||
none()
|
||||
or
|
||||
result = getImmediateChildOfPathExprBase(e, index - b, partialPredicateCall)
|
||||
or
|
||||
result = e.getAttr(index - n) and
|
||||
partialPredicateCall = "Attr(" + (index - n).toString() + ")"
|
||||
or
|
||||
index = nAttr and result = e.getPath() and partialPredicateCall = "Path()"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfStatic(Static e, int index, string partialPredicateCall) {
|
||||
exists(
|
||||
int b, int bExternItem, int bItem, int n, int nAttr, int nBody, int nName, int nTy,
|
||||
@@ -3459,6 +3519,10 @@ private module Impl {
|
||||
// * none() simplifies generation, as we can append `or ...` without a special case for the first item
|
||||
none()
|
||||
or
|
||||
result = getImmediateChildOfFormat(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfFormatArgument(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfMissing(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfUnimplemented(e, index, partialAccessor)
|
||||
@@ -3649,8 +3713,6 @@ private module Impl {
|
||||
or
|
||||
result = getImmediateChildOfParenType(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfPathExpr(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfPathPat(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfPathType(e, index, partialAccessor)
|
||||
@@ -3719,6 +3781,8 @@ private module Impl {
|
||||
or
|
||||
result = getImmediateChildOfExternCrate(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfFormatTemplateVariableAccess(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfFunction(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfImpl(e, index, partialAccessor)
|
||||
@@ -3733,6 +3797,8 @@ private module Impl {
|
||||
or
|
||||
result = getImmediateChildOfModule(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfPathExpr(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfStatic(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfStruct(e, index, partialAccessor)
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
import codeql.rust.elements.Attr
|
||||
import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl
|
||||
import codeql.rust.elements.Path
|
||||
import codeql.rust.elements.internal.PathExprBaseImpl::Impl as PathExprBaseImpl
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the fully generated definition of `PathExpr` and should not
|
||||
@@ -26,7 +26,7 @@ module Generated {
|
||||
* INTERNAL: Do not reference the `Generated::PathExpr` class directly.
|
||||
* Use the subclass `PathExpr`, where the following predicates are available.
|
||||
*/
|
||||
class PathExpr extends Synth::TPathExpr, ExprImpl::Expr {
|
||||
class PathExpr extends Synth::TPathExpr, PathExprBaseImpl::PathExprBase {
|
||||
override string getAPrimaryQlClass() { result = "PathExpr" }
|
||||
|
||||
/**
|
||||
|
||||
22
rust/ql/lib/codeql/rust/elements/internal/generated/PathExprBase.qll
generated
Normal file
22
rust/ql/lib/codeql/rust/elements/internal/generated/PathExprBase.qll
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
// generated by codegen, do not edit
|
||||
/**
|
||||
* This module provides the generated definition of `PathExprBase`.
|
||||
* INTERNAL: Do not import directly.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the fully generated definition of `PathExprBase` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Generated {
|
||||
/**
|
||||
* A path expression or a variable access in a formatting template. See `PathExpr` and `FormatTemplateVariableAccess` for further details.
|
||||
* INTERNAL: Do not reference the `Generated::PathExprBase` class directly.
|
||||
* Use the subclass `PathExprBase`, where the following predicates are available.
|
||||
*/
|
||||
class PathExprBase extends Synth::TPathExprBase, ExprImpl::Expr { }
|
||||
}
|
||||
@@ -3,3 +3,6 @@
|
||||
* This module exports all modules providing `Element` subclasses.
|
||||
*/
|
||||
|
||||
import codeql.rust.elements.internal.FormatConstructor
|
||||
import codeql.rust.elements.internal.FormatArgumentConstructor
|
||||
import codeql.rust.elements.internal.FormatTemplateVariableAccessConstructor
|
||||
|
||||
@@ -2460,27 +2460,9 @@ module Raw {
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* A path expression. For example:
|
||||
* ```rust
|
||||
* let x = variable;
|
||||
* let x = foo::bar;
|
||||
* let y = <T>::foo;
|
||||
* let z = <TypeRef as Trait>::foo;
|
||||
* ```
|
||||
* A path expression or a variable access in a formatting template. See `PathExpr` and `FormatTemplateVariableAccess` for further details.
|
||||
*/
|
||||
class PathExpr extends @path_expr, Expr {
|
||||
override string toString() { result = "PathExpr" }
|
||||
|
||||
/**
|
||||
* Gets the `index`th attr of this path expression (0-based).
|
||||
*/
|
||||
Attr getAttr(int index) { path_expr_attrs(this, index, result) }
|
||||
|
||||
/**
|
||||
* Gets the path of this path expression, if it exists.
|
||||
*/
|
||||
Path getPath() { path_expr_paths(this, result) }
|
||||
}
|
||||
class PathExprBase extends @path_expr_base, Expr { }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
@@ -3608,6 +3590,30 @@ module Raw {
|
||||
Visibility getVisibility() { module_visibilities(this, result) }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* A path expression. For example:
|
||||
* ```rust
|
||||
* let x = variable;
|
||||
* let x = foo::bar;
|
||||
* let y = <T>::foo;
|
||||
* let z = <TypeRef as Trait>::foo;
|
||||
* ```
|
||||
*/
|
||||
class PathExpr extends @path_expr, PathExprBase {
|
||||
override string toString() { result = "PathExpr" }
|
||||
|
||||
/**
|
||||
* Gets the `index`th attr of this path expression (0-based).
|
||||
*/
|
||||
Attr getAttr(int index) { path_expr_attrs(this, index, result) }
|
||||
|
||||
/**
|
||||
* Gets the path of this path expression, if it exists.
|
||||
*/
|
||||
Path getPath() { path_expr_paths(this, result) }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* A Static. For example:
|
||||
|
||||
@@ -150,6 +150,12 @@ module Synth {
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
TForType(Raw::ForType id) { constructForType(id) } or
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
TFormat(Raw::FormatArgsExpr parent, int index, string text, int offset) {
|
||||
constructFormat(parent, index, text, offset)
|
||||
} or
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
@@ -158,6 +164,20 @@ module Synth {
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
TFormatArgsExpr(Raw::FormatArgsExpr id) { constructFormatArgsExpr(id) } or
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
TFormatArgument(
|
||||
Raw::FormatArgsExpr parent, int index, int kind, string name, boolean positional, int offset
|
||||
) {
|
||||
constructFormatArgument(parent, index, kind, name, positional, offset)
|
||||
} or
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
TFormatTemplateVariableAccess(Raw::FormatArgsExpr parent, int index, int kind) {
|
||||
constructFormatTemplateVariableAccess(parent, index, kind)
|
||||
} or
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
@@ -628,7 +648,7 @@ module Synth {
|
||||
TArrayExpr or TAsmExpr or TAwaitExpr or TBecomeExpr or TBinaryExpr or TBlockExpr or
|
||||
TBreakExpr or TCallExprBase or TCastExpr or TClosureExpr or TContinueExpr or TFieldExpr or
|
||||
TForExpr or TFormatArgsExpr or TIfExpr or TIndexExpr or TLetExpr or TLiteralExpr or
|
||||
TLoopExpr or TMacroExpr or TMatchExpr or TOffsetOfExpr or TParenExpr or TPathExpr or
|
||||
TLoopExpr or TMacroExpr or TMatchExpr or TOffsetOfExpr or TParenExpr or TPathExprBase or
|
||||
TPrefixExpr or TRangeExpr or TRecordExpr or TRefExpr or TReturnExpr or TTryExpr or
|
||||
TTupleExpr or TUnderscoreExpr or TWhileExpr or TYeetExpr or TYieldExpr;
|
||||
|
||||
@@ -663,7 +683,7 @@ module Synth {
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
class TLocatable = TAstNode;
|
||||
class TLocatable = TAstNode or TFormat or TFormatArgument;
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
@@ -673,6 +693,11 @@ module Synth {
|
||||
TPathPat or TRangePat or TRecordPat or TRefPat or TRestPat or TSlicePat or TTuplePat or
|
||||
TTupleStructPat or TWildcardPat;
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
class TPathExprBase = TFormatTemplateVariableAccess or TPathExpr;
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
@@ -900,6 +925,12 @@ module Synth {
|
||||
*/
|
||||
TForType convertForTypeFromRaw(Raw::Element e) { result = TForType(e) }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a raw element to a synthesized `TFormat`, if possible.
|
||||
*/
|
||||
TFormat convertFormatFromRaw(Raw::Element e) { none() }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a raw element to a synthesized `TFormatArgsArg`, if possible.
|
||||
@@ -912,6 +943,20 @@ module Synth {
|
||||
*/
|
||||
TFormatArgsExpr convertFormatArgsExprFromRaw(Raw::Element e) { result = TFormatArgsExpr(e) }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a raw element to a synthesized `TFormatArgument`, if possible.
|
||||
*/
|
||||
TFormatArgument convertFormatArgumentFromRaw(Raw::Element e) { none() }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a raw element to a synthesized `TFormatTemplateVariableAccess`, if possible.
|
||||
*/
|
||||
TFormatTemplateVariableAccess convertFormatTemplateVariableAccessFromRaw(Raw::Element e) {
|
||||
none()
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a raw element to a synthesized `TFunction`, if possible.
|
||||
@@ -1781,7 +1826,7 @@ module Synth {
|
||||
or
|
||||
result = convertParenExprFromRaw(e)
|
||||
or
|
||||
result = convertPathExprFromRaw(e)
|
||||
result = convertPathExprBaseFromRaw(e)
|
||||
or
|
||||
result = convertPrefixExprFromRaw(e)
|
||||
or
|
||||
@@ -1900,7 +1945,13 @@ module Synth {
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a raw DB element to a synthesized `TLocatable`, if possible.
|
||||
*/
|
||||
TLocatable convertLocatableFromRaw(Raw::Element e) { result = convertAstNodeFromRaw(e) }
|
||||
TLocatable convertLocatableFromRaw(Raw::Element e) {
|
||||
result = convertAstNodeFromRaw(e)
|
||||
or
|
||||
result = convertFormatFromRaw(e)
|
||||
or
|
||||
result = convertFormatArgumentFromRaw(e)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
@@ -1940,6 +1991,16 @@ module Synth {
|
||||
result = convertWildcardPatFromRaw(e)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a raw DB element to a synthesized `TPathExprBase`, if possible.
|
||||
*/
|
||||
TPathExprBase convertPathExprBaseFromRaw(Raw::Element e) {
|
||||
result = convertFormatTemplateVariableAccessFromRaw(e)
|
||||
or
|
||||
result = convertPathExprFromRaw(e)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a raw DB element to a synthesized `TStmt`, if possible.
|
||||
@@ -2206,6 +2267,12 @@ module Synth {
|
||||
*/
|
||||
Raw::Element convertForTypeToRaw(TForType e) { e = TForType(result) }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a synthesized `TFormat` to a raw DB element, if possible.
|
||||
*/
|
||||
Raw::Element convertFormatToRaw(TFormat e) { none() }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a synthesized `TFormatArgsArg` to a raw DB element, if possible.
|
||||
@@ -2218,6 +2285,18 @@ module Synth {
|
||||
*/
|
||||
Raw::Element convertFormatArgsExprToRaw(TFormatArgsExpr e) { e = TFormatArgsExpr(result) }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a synthesized `TFormatArgument` to a raw DB element, if possible.
|
||||
*/
|
||||
Raw::Element convertFormatArgumentToRaw(TFormatArgument e) { none() }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a synthesized `TFormatTemplateVariableAccess` to a raw DB element, if possible.
|
||||
*/
|
||||
Raw::Element convertFormatTemplateVariableAccessToRaw(TFormatTemplateVariableAccess e) { none() }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a synthesized `TFunction` to a raw DB element, if possible.
|
||||
@@ -3087,7 +3166,7 @@ module Synth {
|
||||
or
|
||||
result = convertParenExprToRaw(e)
|
||||
or
|
||||
result = convertPathExprToRaw(e)
|
||||
result = convertPathExprBaseToRaw(e)
|
||||
or
|
||||
result = convertPrefixExprToRaw(e)
|
||||
or
|
||||
@@ -3206,7 +3285,13 @@ module Synth {
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a synthesized `TLocatable` to a raw DB element, if possible.
|
||||
*/
|
||||
Raw::Element convertLocatableToRaw(TLocatable e) { result = convertAstNodeToRaw(e) }
|
||||
Raw::Element convertLocatableToRaw(TLocatable e) {
|
||||
result = convertAstNodeToRaw(e)
|
||||
or
|
||||
result = convertFormatToRaw(e)
|
||||
or
|
||||
result = convertFormatArgumentToRaw(e)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
@@ -3246,6 +3331,16 @@ module Synth {
|
||||
result = convertWildcardPatToRaw(e)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a synthesized `TPathExprBase` to a raw DB element, if possible.
|
||||
*/
|
||||
Raw::Element convertPathExprBaseToRaw(TPathExprBase e) {
|
||||
result = convertFormatTemplateVariableAccessToRaw(e)
|
||||
or
|
||||
result = convertPathExprToRaw(e)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a synthesized `TStmt` to a raw DB element, if possible.
|
||||
|
||||
@@ -37,8 +37,11 @@ import codeql.rust.elements.internal.FieldExprConstructor
|
||||
import codeql.rust.elements.internal.FnPtrTypeConstructor
|
||||
import codeql.rust.elements.internal.ForExprConstructor
|
||||
import codeql.rust.elements.internal.ForTypeConstructor
|
||||
import codeql.rust.elements.internal.FormatConstructor
|
||||
import codeql.rust.elements.internal.FormatArgsArgConstructor
|
||||
import codeql.rust.elements.internal.FormatArgsExprConstructor
|
||||
import codeql.rust.elements.internal.FormatArgumentConstructor
|
||||
import codeql.rust.elements.internal.FormatTemplateVariableAccessConstructor
|
||||
import codeql.rust.elements.internal.FunctionConstructor
|
||||
import codeql.rust.elements.internal.GenericArgListConstructor
|
||||
import codeql.rust.elements.internal.GenericParamListConstructor
|
||||
|
||||
65
rust/ql/lib/codeql/rust/internal/CachedStages.qll
Normal file
65
rust/ql/lib/codeql/rust/internal/CachedStages.qll
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* The purpose of this file is to control which cached predicates belong to the same stage.
|
||||
*
|
||||
* Combining stages can improve performance as we are more likely to reuse shared, non-cached predicates.
|
||||
*
|
||||
* To make a predicate `p` belong to a stage `A`:
|
||||
* - make `p` depend on `A::ref()`, and
|
||||
* - make `A::backref()` depend on `p`.
|
||||
*
|
||||
* Since `A` is a cached module, `ref` and `backref` must be in the same stage, and the dependency
|
||||
* chain above thus forces `p` to be in that stage as well.
|
||||
*
|
||||
* With these two predicates in a `cached module` we ensure that all the cached predicates will be in a single stage at runtime.
|
||||
*
|
||||
* Grouping stages can cause unnecessary computation, as a concrete query might not depend on
|
||||
* all the cached predicates in a stage.
|
||||
* Care should therefore be taken not to combine two stages, if it is likely that a query only depend
|
||||
* on some but not all the cached predicates in the combined stage.
|
||||
*/
|
||||
|
||||
import rust
|
||||
|
||||
/**
|
||||
* Contains a `cached module` for each stage.
|
||||
* Each `cached module` ensures that predicates that are supposed to be in the same stage, are in the same stage.
|
||||
*
|
||||
* Each `cached module` contain two predicates:
|
||||
* The first, `ref`, always holds, and is referenced from `cached` predicates.
|
||||
* The second, `backref`, contains references to the same `cached` predicates.
|
||||
* The `backref` predicate starts with `1 = 1 or` to ensure that the predicate will be optimized down to a constant by the optimizer.
|
||||
*/
|
||||
module Stages {
|
||||
/**
|
||||
* The control flow graph (CFG) stage.
|
||||
*/
|
||||
cached
|
||||
module CfgStage {
|
||||
private import codeql.rust.controlflow.internal.Splitting
|
||||
private import codeql.rust.controlflow.internal.SuccessorType
|
||||
private import codeql.rust.controlflow.internal.ControlFlowGraphImpl
|
||||
|
||||
/**
|
||||
* Always holds.
|
||||
* Ensures that a predicate is evaluated as part of the BasicBlocks stage.
|
||||
*/
|
||||
cached
|
||||
predicate ref() { 1 = 1 }
|
||||
|
||||
/**
|
||||
* DO NOT USE!
|
||||
*
|
||||
* Contains references to each predicate that use the above `ref` predicate.
|
||||
*/
|
||||
cached
|
||||
predicate backref() {
|
||||
1 = 1
|
||||
or
|
||||
exists(TConditionalCompletionSplitKind())
|
||||
or
|
||||
exists(TNormalSuccessor())
|
||||
or
|
||||
exists(AstCfgNode n)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,7 +310,7 @@ closure_binder_generic_param_lists(
|
||||
| @match_expr
|
||||
| @offset_of_expr
|
||||
| @paren_expr
|
||||
| @path_expr
|
||||
| @path_expr_base
|
||||
| @prefix_expr
|
||||
| @range_expr
|
||||
| @record_expr
|
||||
@@ -2113,22 +2113,9 @@ paren_type_ties(
|
||||
int ty: @type_ref ref
|
||||
);
|
||||
|
||||
path_exprs(
|
||||
unique int id: @path_expr
|
||||
);
|
||||
|
||||
#keyset[id, index]
|
||||
path_expr_attrs(
|
||||
int id: @path_expr ref,
|
||||
int index: int ref,
|
||||
int attr: @attr ref
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
path_expr_paths(
|
||||
int id: @path_expr ref,
|
||||
int path: @path ref
|
||||
);
|
||||
@path_expr_base =
|
||||
@path_expr
|
||||
;
|
||||
|
||||
path_pats(
|
||||
unique int id: @path_pat
|
||||
@@ -3036,6 +3023,23 @@ module_visibilities(
|
||||
int visibility: @visibility ref
|
||||
);
|
||||
|
||||
path_exprs(
|
||||
unique int id: @path_expr
|
||||
);
|
||||
|
||||
#keyset[id, index]
|
||||
path_expr_attrs(
|
||||
int id: @path_expr ref,
|
||||
int index: int ref,
|
||||
int attr: @attr ref
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
path_expr_paths(
|
||||
int id: @path_expr ref,
|
||||
int path: @path ref
|
||||
);
|
||||
|
||||
statics(
|
||||
unique int id: @static
|
||||
);
|
||||
|
||||
@@ -6,3 +6,5 @@ import codeql.files.FileSystem
|
||||
import codeql.rust.elements.AssignmentOperation
|
||||
import codeql.rust.elements.LogicalOperation
|
||||
import codeql.rust.elements.Variable
|
||||
import codeql.rust.elements.NamedFormatArgument
|
||||
import codeql.rust.elements.PositionalFormatArgument
|
||||
|
||||
132
rust/ql/test/library-tests/formatstrings/FormatTemplate.expected
Normal file
132
rust/ql/test/library-tests/formatstrings/FormatTemplate.expected
Normal file
@@ -0,0 +1,132 @@
|
||||
getFormat
|
||||
| main.rs:5:14:5:61 | FormatArgsExpr | main.rs:5:21:5:46 | {value:#width$.precision$} | 0 |
|
||||
| main.rs:6:14:6:56 | FormatArgsExpr | main.rs:6:21:6:30 | {0:#1$.2$} | 0 |
|
||||
| main.rs:7:14:7:40 | FormatArgsExpr | main.rs:7:21:7:22 | {} | 0 |
|
||||
| main.rs:7:14:7:40 | FormatArgsExpr | main.rs:7:24:7:25 | {} | 1 |
|
||||
| main.rs:11:14:11:34 | FormatArgsExpr | main.rs:11:22:11:23 | {} | 0 |
|
||||
| main.rs:12:14:12:34 | FormatArgsExpr | main.rs:12:29:12:30 | {} | 0 |
|
||||
| main.rs:13:14:13:27 | FormatArgsExpr | main.rs:13:15:13:18 | {:?} | 0 |
|
||||
| main.rs:14:14:14:33 | FormatArgsExpr | main.rs:14:15:14:21 | {value} | 0 |
|
||||
| main.rs:16:14:16:30 | FormatArgsExpr | main.rs:16:21:16:28 | {people} | 0 |
|
||||
| main.rs:17:14:17:26 | FormatArgsExpr | main.rs:17:15:17:16 | {} | 0 |
|
||||
| main.rs:17:14:17:26 | FormatArgsExpr | main.rs:17:18:17:19 | {} | 1 |
|
||||
| main.rs:18:14:18:24 | FormatArgsExpr | main.rs:18:15:18:19 | {:04} | 0 |
|
||||
| main.rs:19:14:19:32 | FormatArgsExpr | main.rs:19:15:19:19 | {:#?} | 0 |
|
||||
| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:15:21:17 | {1} | 0 |
|
||||
| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:19:21:20 | {} | 1 |
|
||||
| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:22:21:24 | {0} | 2 |
|
||||
| main.rs:21:14:21:34 | FormatArgsExpr | main.rs:21:26:21:27 | {} | 3 |
|
||||
| main.rs:22:14:22:31 | FormatArgsExpr | main.rs:22:21:22:24 | {:5} | 0 |
|
||||
| main.rs:23:14:23:35 | FormatArgsExpr | main.rs:23:21:23:25 | {:1$} | 0 |
|
||||
| main.rs:24:14:24:36 | FormatArgsExpr | main.rs:24:21:24:26 | {1:0$} | 0 |
|
||||
| main.rs:25:14:25:47 | FormatArgsExpr | main.rs:25:21:25:29 | {:width$} | 0 |
|
||||
| main.rs:27:14:27:36 | FormatArgsExpr | main.rs:27:21:27:29 | {:width$} | 0 |
|
||||
| main.rs:28:24:28:42 | FormatArgsExpr | main.rs:28:31:28:35 | {:<5} | 0 |
|
||||
| main.rs:29:24:29:43 | FormatArgsExpr | main.rs:29:31:29:36 | {:-<5} | 0 |
|
||||
| main.rs:30:24:30:42 | FormatArgsExpr | main.rs:30:31:30:35 | {:^5} | 0 |
|
||||
| main.rs:31:24:31:42 | FormatArgsExpr | main.rs:31:31:31:35 | {:>5} | 0 |
|
||||
| main.rs:32:14:32:57 | FormatArgsExpr | main.rs:32:21:32:26 | {:^15} | 0 |
|
||||
| main.rs:32:39:32:56 | FormatArgsExpr | main.rs:32:40:32:43 | {:?} | 0 |
|
||||
| main.rs:33:24:33:39 | FormatArgsExpr | main.rs:33:31:33:34 | {:+} | 0 |
|
||||
| main.rs:34:24:34:35 | FormatArgsExpr | main.rs:34:25:34:29 | {:#x} | 0 |
|
||||
| main.rs:35:24:35:40 | FormatArgsExpr | main.rs:35:31:35:35 | {:05} | 0 |
|
||||
| main.rs:36:24:36:41 | FormatArgsExpr | main.rs:36:31:36:35 | {:05} | 0 |
|
||||
| main.rs:37:24:37:38 | FormatArgsExpr | main.rs:37:25:37:32 | {:#010x} | 0 |
|
||||
| main.rs:39:14:39:45 | FormatArgsExpr | main.rs:39:21:39:23 | {0} | 0 |
|
||||
| main.rs:39:14:39:45 | FormatArgsExpr | main.rs:39:28:39:33 | {1:.5} | 1 |
|
||||
| main.rs:41:14:41:49 | FormatArgsExpr | main.rs:41:21:41:23 | {1} | 0 |
|
||||
| main.rs:41:14:41:49 | FormatArgsExpr | main.rs:41:28:41:34 | {2:.0$} | 1 |
|
||||
| main.rs:43:14:43:49 | FormatArgsExpr | main.rs:43:21:43:23 | {0} | 0 |
|
||||
| main.rs:43:14:43:49 | FormatArgsExpr | main.rs:43:28:43:34 | {2:.1$} | 1 |
|
||||
| main.rs:45:14:45:46 | FormatArgsExpr | main.rs:45:21:45:22 | {} | 0 |
|
||||
| main.rs:45:14:45:46 | FormatArgsExpr | main.rs:45:27:45:31 | {:.*} | 1 |
|
||||
| main.rs:47:14:47:48 | FormatArgsExpr | main.rs:47:21:47:23 | {1} | 0 |
|
||||
| main.rs:47:14:47:48 | FormatArgsExpr | main.rs:47:28:47:33 | {2:.*} | 1 |
|
||||
| main.rs:48:14:48:47 | FormatArgsExpr | main.rs:48:21:48:22 | {} | 0 |
|
||||
| main.rs:48:14:48:47 | FormatArgsExpr | main.rs:48:27:48:32 | {2:.*} | 1 |
|
||||
| main.rs:49:14:49:72 | FormatArgsExpr | main.rs:49:21:49:22 | {} | 0 |
|
||||
| main.rs:49:14:49:72 | FormatArgsExpr | main.rs:49:27:49:41 | {number:.prec$} | 1 |
|
||||
| main.rs:52:9:55:22 | FormatArgsExpr | main.rs:52:10:52:11 | {} | 0 |
|
||||
| main.rs:52:9:55:22 | FormatArgsExpr | main.rs:52:15:52:23 | {name:.*} | 1 |
|
||||
| main.rs:58:9:61:24 | FormatArgsExpr | main.rs:58:10:58:11 | {} | 0 |
|
||||
| main.rs:58:9:61:24 | FormatArgsExpr | main.rs:58:15:58:23 | {name:.*} | 1 |
|
||||
| main.rs:64:9:67:24 | FormatArgsExpr | main.rs:64:10:64:11 | {} | 0 |
|
||||
| main.rs:64:9:67:24 | FormatArgsExpr | main.rs:64:15:64:25 | {name:>8.*} | 1 |
|
||||
| main.rs:70:12:70:31 | FormatArgsExpr | main.rs:70:13:70:20 | {0:.1$e} | 0 |
|
||||
| main.rs:71:12:71:31 | FormatArgsExpr | main.rs:71:13:71:20 | {0:.1$e} | 0 |
|
||||
| main.rs:73:14:73:35 | FormatArgsExpr | main.rs:73:28:73:29 | {} | 0 |
|
||||
getArgumentRef
|
||||
| main.rs:5:21:5:46 | {value:#width$.precision$} | main.rs:5:22:5:26 | value |
|
||||
| main.rs:6:21:6:30 | {0:#1$.2$} | main.rs:6:22:6:22 | 0 |
|
||||
| main.rs:14:15:14:21 | {value} | main.rs:14:16:14:20 | value |
|
||||
| main.rs:16:21:16:28 | {people} | main.rs:16:22:16:27 | people |
|
||||
| main.rs:21:15:21:17 | {1} | main.rs:21:16:21:16 | 1 |
|
||||
| main.rs:21:22:21:24 | {0} | main.rs:21:23:21:23 | 0 |
|
||||
| main.rs:24:21:24:26 | {1:0$} | main.rs:24:22:24:22 | 1 |
|
||||
| main.rs:39:21:39:23 | {0} | main.rs:39:22:39:22 | 0 |
|
||||
| main.rs:39:28:39:33 | {1:.5} | main.rs:39:29:39:29 | 1 |
|
||||
| main.rs:41:21:41:23 | {1} | main.rs:41:22:41:22 | 1 |
|
||||
| main.rs:41:28:41:34 | {2:.0$} | main.rs:41:29:41:29 | 2 |
|
||||
| main.rs:43:21:43:23 | {0} | main.rs:43:22:43:22 | 0 |
|
||||
| main.rs:43:28:43:34 | {2:.1$} | main.rs:43:29:43:29 | 2 |
|
||||
| main.rs:47:21:47:23 | {1} | main.rs:47:22:47:22 | 1 |
|
||||
| main.rs:47:28:47:33 | {2:.*} | main.rs:47:29:47:29 | 2 |
|
||||
| main.rs:48:27:48:32 | {2:.*} | main.rs:48:28:48:28 | 2 |
|
||||
| main.rs:49:27:49:41 | {number:.prec$} | main.rs:49:28:49:33 | number |
|
||||
| main.rs:52:15:52:23 | {name:.*} | main.rs:52:16:52:19 | name |
|
||||
| main.rs:58:15:58:23 | {name:.*} | main.rs:58:16:58:19 | name |
|
||||
| main.rs:64:15:64:25 | {name:>8.*} | main.rs:64:16:64:19 | name |
|
||||
| main.rs:70:13:70:20 | {0:.1$e} | main.rs:70:14:70:14 | 0 |
|
||||
| main.rs:71:13:71:20 | {0:.1$e} | main.rs:71:14:71:14 | 0 |
|
||||
getWidthArgument
|
||||
| main.rs:5:21:5:46 | {value:#width$.precision$} | main.rs:5:29:5:33 | width |
|
||||
| main.rs:6:21:6:30 | {0:#1$.2$} | main.rs:6:25:6:25 | 1 |
|
||||
| main.rs:23:21:23:25 | {:1$} | main.rs:23:23:23:23 | 1 |
|
||||
| main.rs:24:21:24:26 | {1:0$} | main.rs:24:24:24:24 | 0 |
|
||||
| main.rs:25:21:25:29 | {:width$} | main.rs:25:23:25:27 | width |
|
||||
| main.rs:27:21:27:29 | {:width$} | main.rs:27:23:27:27 | width |
|
||||
getPrecisionArgument
|
||||
| main.rs:5:21:5:46 | {value:#width$.precision$} | main.rs:5:36:5:44 | precision |
|
||||
| main.rs:6:21:6:30 | {0:#1$.2$} | main.rs:6:28:6:28 | 2 |
|
||||
| main.rs:41:28:41:34 | {2:.0$} | main.rs:41:32:41:32 | 0 |
|
||||
| main.rs:43:28:43:34 | {2:.1$} | main.rs:43:32:43:32 | 1 |
|
||||
| main.rs:49:27:49:41 | {number:.prec$} | main.rs:49:36:49:39 | prec |
|
||||
| main.rs:70:13:70:20 | {0:.1$e} | main.rs:70:17:70:17 | 1 |
|
||||
| main.rs:71:13:71:20 | {0:.1$e} | main.rs:71:17:71:17 | 1 |
|
||||
getIndex
|
||||
| main.rs:6:22:6:22 | 0 | 0 |
|
||||
| main.rs:6:25:6:25 | 1 | 1 |
|
||||
| main.rs:6:28:6:28 | 2 | 2 |
|
||||
| main.rs:21:16:21:16 | 1 | 1 |
|
||||
| main.rs:21:23:21:23 | 0 | 0 |
|
||||
| main.rs:23:23:23:23 | 1 | 1 |
|
||||
| main.rs:24:22:24:22 | 1 | 1 |
|
||||
| main.rs:24:24:24:24 | 0 | 0 |
|
||||
| main.rs:39:22:39:22 | 0 | 0 |
|
||||
| main.rs:39:29:39:29 | 1 | 1 |
|
||||
| main.rs:41:22:41:22 | 1 | 1 |
|
||||
| main.rs:41:29:41:29 | 2 | 2 |
|
||||
| main.rs:41:32:41:32 | 0 | 0 |
|
||||
| main.rs:43:22:43:22 | 0 | 0 |
|
||||
| main.rs:43:29:43:29 | 2 | 2 |
|
||||
| main.rs:43:32:43:32 | 1 | 1 |
|
||||
| main.rs:47:22:47:22 | 1 | 1 |
|
||||
| main.rs:47:29:47:29 | 2 | 2 |
|
||||
| main.rs:48:28:48:28 | 2 | 2 |
|
||||
| main.rs:70:14:70:14 | 0 | 0 |
|
||||
| main.rs:70:17:70:17 | 1 | 1 |
|
||||
| main.rs:71:14:71:14 | 0 | 0 |
|
||||
| main.rs:71:17:71:17 | 1 | 1 |
|
||||
getName
|
||||
| main.rs:5:22:5:26 | value | value |
|
||||
| main.rs:5:29:5:33 | width | width |
|
||||
| main.rs:5:36:5:44 | precision | precision |
|
||||
| main.rs:14:16:14:20 | value | value |
|
||||
| main.rs:16:22:16:27 | people | people |
|
||||
| main.rs:25:23:25:27 | width | width |
|
||||
| main.rs:27:23:27:27 | width | width |
|
||||
| main.rs:49:28:49:33 | number | number |
|
||||
| main.rs:49:36:49:39 | prec | prec |
|
||||
| main.rs:52:16:52:19 | name | name |
|
||||
| main.rs:58:16:58:19 | name | name |
|
||||
| main.rs:64:16:64:19 | name | name |
|
||||
19
rust/ql/test/library-tests/formatstrings/FormatTemplate.ql
Normal file
19
rust/ql/test/library-tests/formatstrings/FormatTemplate.ql
Normal file
@@ -0,0 +1,19 @@
|
||||
import rust
|
||||
|
||||
query predicate getFormat(FormatArgsExpr arg, Format format, int index) {
|
||||
format = arg.getFormat(index)
|
||||
}
|
||||
|
||||
query predicate getArgumentRef(Format format, FormatArgument arg) { arg = format.getArgumentRef() }
|
||||
|
||||
query predicate getWidthArgument(Format format, FormatArgument arg) {
|
||||
arg = format.getWidthArgument()
|
||||
}
|
||||
|
||||
query predicate getPrecisionArgument(Format format, FormatArgument arg) {
|
||||
arg = format.getPrecisionArgument()
|
||||
}
|
||||
|
||||
query predicate getIndex(PositionalFormatArgument arg, int index) { arg.getIndex() = index }
|
||||
|
||||
query predicate getName(NamedFormatArgument arg, string name) { arg.getName() = name }
|
||||
77
rust/ql/test/library-tests/formatstrings/main.rs
Normal file
77
rust/ql/test/library-tests/formatstrings/main.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
fn main() {
|
||||
let width = 4;
|
||||
let precision = 2;
|
||||
let value = 10;
|
||||
println!("Value {value:#width$.precision$}", value = 10.5);
|
||||
println!("Value {0:#1$.2$}", value, width, precision);
|
||||
println!("Value {} {}", value, width);
|
||||
|
||||
// Examples from https://doc.rust-lang.org/std/fmt
|
||||
println!("Hello");
|
||||
println!("Hello, {}!", "world");
|
||||
println!("The number is {}", 1);
|
||||
println!("{:?}", (3, 4));
|
||||
println!("{value}", value = 4);
|
||||
let people = "Rustaceans";
|
||||
println!("Hello {people}!");
|
||||
println!("{} {}", 1, 2);
|
||||
println!("{:04}", 42);
|
||||
println!("{:#?}", (100, 200));
|
||||
|
||||
println!("{1} {} {0} {}", 1, 2);
|
||||
println!("Hello {:5}!", "x");
|
||||
println!("Hello {:1$}!", "x", 5);
|
||||
println!("Hello {1:0$}!", 5, "x");
|
||||
println!("Hello {:width$}!", "x", width = 5);
|
||||
let width = 5;
|
||||
println!("Hello {:width$}!", "x");
|
||||
assert_eq!(format!("Hello {:<5}!", "x"), "Hello x !");
|
||||
assert_eq!(format!("Hello {:-<5}!", "x"), "Hello x----!");
|
||||
assert_eq!(format!("Hello {:^5}!", "x"), "Hello x !");
|
||||
assert_eq!(format!("Hello {:>5}!", "x"), "Hello x!");
|
||||
println!("Hello {:^15}!", format!("{:?}", Some("hi")));
|
||||
assert_eq!(format!("Hello {:+}!", 5), "Hello +5!");
|
||||
assert_eq!(format!("{:#x}!", 27), "0x1b!");
|
||||
assert_eq!(format!("Hello {:05}!", 5), "Hello 00005!");
|
||||
assert_eq!(format!("Hello {:05}!", -5), "Hello -0005!");
|
||||
assert_eq!(format!("{:#010x}!", 27), "0x0000001b!");
|
||||
|
||||
println!("Hello {0} is {1:.5}", "x", 0.01);
|
||||
|
||||
println!("Hello {1} is {2:.0$}", 5, "x", 0.01);
|
||||
|
||||
println!("Hello {0} is {2:.1$}", "x", 5, 0.01);
|
||||
|
||||
println!("Hello {} is {:.*}", "x", 5, 0.01);
|
||||
|
||||
println!("Hello {1} is {2:.*}", 5, "x", 0.01);
|
||||
println!("Hello {} is {2:.*}", "x", 5, 0.01);
|
||||
println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
|
||||
|
||||
println!(
|
||||
"{}, `{name:.*}` has 3 fractional digits",
|
||||
"Hello",
|
||||
3,
|
||||
name = 1234.56
|
||||
);
|
||||
println!(
|
||||
"{}, `{name:.*}` has 3 characters",
|
||||
"Hello",
|
||||
3,
|
||||
name = "1234.56"
|
||||
);
|
||||
println!(
|
||||
"{}, `{name:>8.*}` has 3 right-aligned characters",
|
||||
"Hello",
|
||||
3,
|
||||
name = "1234.56"
|
||||
);
|
||||
|
||||
print!("{0:.1$e}", 12345, 3);
|
||||
print!("{0:.1$e}", 12355, 3);
|
||||
|
||||
println!("The value is {}", 1.5);
|
||||
|
||||
assert_eq!(format!("Hello {{}}"), "Hello {}");
|
||||
assert_eq!(format!("{{ Hello"), "{ Hello");
|
||||
}
|
||||
@@ -19,15 +19,10 @@
|
||||
| main.rs:370:9:370:9 | x | Variable is assigned a value that is never used. |
|
||||
| main.rs:378:17:378:17 | x | Variable is assigned a value that is never used. |
|
||||
| main.rs:432:9:432:10 | i6 | Variable is assigned a value that is never used. |
|
||||
| more.rs:8:9:8:13 | times | Variable is assigned a value that is never used. |
|
||||
| more.rs:9:9:9:14 | unused | Variable is assigned a value that is never used. |
|
||||
| more.rs:21:9:21:14 | unused | Variable is assigned a value that is never used. |
|
||||
| more.rs:38:23:38:25 | val | Variable is assigned a value that is never used. |
|
||||
| more.rs:42:19:42:21 | val | Variable is assigned a value that is never used. |
|
||||
| more.rs:58:9:58:11 | val | Variable is assigned a value that is never used. |
|
||||
| more.rs:80:9:80:14 | a_ptr4 | Variable is assigned a value that is never used. |
|
||||
| more.rs:95:9:95:13 | d_ptr | Variable is assigned a value that is never used. |
|
||||
| more.rs:101:9:101:17 | f_ptr | Variable is assigned a value that is never used. |
|
||||
| more.rs:24:9:24:11 | val | Variable is assigned a value that is never used. |
|
||||
| more.rs:46:9:46:14 | a_ptr4 | Variable is assigned a value that is never used. |
|
||||
| more.rs:61:9:61:13 | d_ptr | Variable is assigned a value that is never used. |
|
||||
| more.rs:67:9:67:17 | f_ptr | Variable is assigned a value that is never used. |
|
||||
| unreachable.rs:166:6:166:6 | x | Variable is assigned a value that is never used. |
|
||||
| unreachable.rs:190:14:190:14 | a | Variable is assigned a value that is never used. |
|
||||
| unreachable.rs:199:9:199:9 | a | Variable is assigned a value that is never used. |
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
| main.rs:90:13:90:13 | d | Variable is not used. |
|
||||
| main.rs:141:5:141:5 | y | Variable is not used. |
|
||||
| main.rs:168:9:168:9 | x | Variable is not used. |
|
||||
| main.rs:196:9:196:9 | x | Variable is not used. |
|
||||
| main.rs:201:9:201:9 | x | Variable is not used. |
|
||||
| main.rs:250:17:250:17 | a | Variable is not used. |
|
||||
| main.rs:258:20:258:22 | val | Variable is not used. |
|
||||
| main.rs:272:14:272:16 | val | Variable is not used. |
|
||||
@@ -20,3 +18,4 @@
|
||||
| main.rs:379:21:379:21 | y | Variable is not used. |
|
||||
| main.rs:427:27:427:29 | val | Variable is not used. |
|
||||
| main.rs:430:22:430:24 | acc | Variable is not used. |
|
||||
| main.rs:455:9:455:14 | unused | Variable is not used. |
|
||||
|
||||
@@ -193,12 +193,12 @@ fn loops() {
|
||||
}
|
||||
}
|
||||
|
||||
for x // SPURIOUS: unused variable
|
||||
for x
|
||||
in 1..10 {
|
||||
println!("x is {x}");
|
||||
}
|
||||
|
||||
for x // SPURIOUS: unused variable
|
||||
for x
|
||||
in 1..10 {
|
||||
_ = format!("x is {x}"); // SPURIOUS: unused value `res`
|
||||
}
|
||||
@@ -434,6 +434,38 @@ fn folds_and_closures() {
|
||||
_ = a6.fold(0, | acc, val | acc + val + i6);
|
||||
}
|
||||
|
||||
// --- traits ---
|
||||
|
||||
trait Incrementable {
|
||||
fn increment(
|
||||
&mut self,
|
||||
times: i32,
|
||||
unused: &mut i32
|
||||
);
|
||||
}
|
||||
|
||||
struct MyValue {
|
||||
value: i32,
|
||||
}
|
||||
|
||||
impl Incrementable for MyValue {
|
||||
fn increment(
|
||||
&mut self,
|
||||
times: i32,
|
||||
unused: i32 // BAD: unused variable
|
||||
) {
|
||||
self.value += times;
|
||||
}
|
||||
}
|
||||
|
||||
fn traits() {
|
||||
let mut i = MyValue { value: 0 };
|
||||
let a = 1;
|
||||
let b = 2;
|
||||
|
||||
i.increment(a, b);
|
||||
}
|
||||
|
||||
// --- main ---
|
||||
|
||||
fn main() {
|
||||
|
||||
@@ -1,45 +1,11 @@
|
||||
|
||||
|
||||
// --- traits ---
|
||||
|
||||
trait Incrementable {
|
||||
fn increment(
|
||||
&mut self,
|
||||
times: i32, // SPURIOUS: unused value
|
||||
unused: i32 // SPURIOUS: unused value
|
||||
);
|
||||
}
|
||||
|
||||
struct MyValue {
|
||||
value: i32,
|
||||
}
|
||||
|
||||
impl Incrementable for MyValue {
|
||||
fn increment(
|
||||
&mut self,
|
||||
times: i32,
|
||||
unused: i32 // BAD: unused variable [NOT DETECTED] SPURIOUS: unused value
|
||||
) {
|
||||
self.value += times;
|
||||
}
|
||||
}
|
||||
|
||||
fn traits() {
|
||||
let mut i = MyValue { value: 0 };
|
||||
let a = 1;
|
||||
let b = 2;
|
||||
|
||||
i.increment(a, b);
|
||||
}
|
||||
|
||||
// --- generics ---
|
||||
|
||||
trait MySettable<T> {
|
||||
fn set(&mut self, val: T); // SPURIOUS: unused value
|
||||
fn set(&mut self, val: T);
|
||||
}
|
||||
|
||||
trait MyGettable<T> {
|
||||
fn get(&self, val: T) -> &T; // SPURIOUS: unused value
|
||||
fn get(&self, val: T) -> &T;
|
||||
}
|
||||
|
||||
struct MyContainer<T> {
|
||||
|
||||
@@ -101,7 +101,13 @@ class _:
|
||||
"""
|
||||
|
||||
|
||||
@annotate(PathExpr)
|
||||
class PathExprBase(Expr):
|
||||
"""
|
||||
A path expression or a variable access in a formatting template. See `PathExpr` and `FormatTemplateVariableAccess` for further details.
|
||||
"""
|
||||
|
||||
|
||||
@annotate(PathExpr, replace_bases={Expr: PathExprBase})
|
||||
class _:
|
||||
"""
|
||||
A path expression. For example:
|
||||
@@ -191,6 +197,7 @@ class _:
|
||||
```
|
||||
"""
|
||||
|
||||
|
||||
class CallExprBase(Expr):
|
||||
"""
|
||||
A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details.
|
||||
@@ -213,6 +220,7 @@ class _:
|
||||
arg_list: drop
|
||||
attrs: drop
|
||||
|
||||
|
||||
@annotate(MethodCallExpr, replace_bases={Expr: CallExprBase})
|
||||
class _:
|
||||
"""
|
||||
@@ -1741,6 +1749,7 @@ class _:
|
||||
```
|
||||
"""
|
||||
|
||||
|
||||
@annotate(Function, add_bases=[Callable])
|
||||
class _:
|
||||
param_list: drop
|
||||
@@ -1751,3 +1760,38 @@ class _:
|
||||
class _:
|
||||
param_list: drop
|
||||
attrs: drop
|
||||
|
||||
|
||||
@qltest.skip
|
||||
@synth.on_arguments(parent="FormatArgsExpr", index=int, kind=int)
|
||||
class FormatTemplateVariableAccess(PathExprBase):
|
||||
pass
|
||||
|
||||
|
||||
@qltest.skip
|
||||
@synth.on_arguments(parent=FormatArgsExpr, index=int, text=string, offset=int)
|
||||
class Format(Locatable):
|
||||
"""
|
||||
A format element in a formatting template. For example the `{}` in:
|
||||
```rust
|
||||
println!("Hello {}", "world");
|
||||
```
|
||||
"""
|
||||
parent: FormatArgsExpr
|
||||
index: int
|
||||
|
||||
|
||||
@qltest.skip
|
||||
@synth.on_arguments(parent=FormatArgsExpr, index=int, kind=int, name=string, positional=boolean, offset=int)
|
||||
class FormatArgument(Locatable):
|
||||
"""
|
||||
An argument in a format element in a formatting template. For example the `width`, `precision`, and `value` in:
|
||||
```rust
|
||||
println!("Value {value:#width$.precision$}");
|
||||
```
|
||||
or the `0`, `1` and `2` in:
|
||||
```rust
|
||||
println!("Value {0:#1$.2$}", value, width, precision);
|
||||
```
|
||||
"""
|
||||
parent: Format
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
set "RUST_BACKTRACE=full"
|
||||
set "QLTEST_LOG=%CODEQL_EXTRACTOR_RUST_LOG_DIR%/qltest.log"
|
||||
|
||||
type NUL && "%CODEQL_EXTRACTOR_RUST_ROOT%/tools/%CODEQL_PLATFORM%/extractor" --qltest >"%QLTEST_LOG%"
|
||||
type NUL && "%CODEQL_EXTRACTOR_RUST_ROOT%/tools/%CODEQL_PLATFORM%/extractor" --qltest >"%QLTEST_LOG%" 2>&1
|
||||
|
||||
if %ERRORLEVEL% neq 0 (
|
||||
type "%QLTEST_LOG%"
|
||||
|
||||
@@ -4,7 +4,7 @@ set -eu
|
||||
|
||||
export RUST_BACKTRACE=full
|
||||
QLTEST_LOG="$CODEQL_EXTRACTOR_RUST_LOG_DIR"/qltest.log
|
||||
if ! "$CODEQL_EXTRACTOR_RUST_ROOT/tools/$CODEQL_PLATFORM/extractor" --qltest &>> "$QLTEST_LOG"; then
|
||||
if ! "$CODEQL_EXTRACTOR_RUST_ROOT/tools/$CODEQL_PLATFORM/extractor" --qltest >> "$QLTEST_LOG" 2>&1; then
|
||||
cat "$QLTEST_LOG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user