From 5f9e676e150cf475e0cdaff8854e429c841fabe4 Mon Sep 17 00:00:00 2001 From: Andrzej Janik Date: Thu, 4 Sep 2025 00:49:55 +0000 Subject: [PATCH] Count invalid directives instead of returning semi-broken ones --- Cargo.lock | 10 ++---- ptx/Cargo.toml | 2 +- ptx_parser/Cargo.toml | 2 +- ptx_parser/src/ast.rs | 1 + ptx_parser/src/lib.rs | 76 +++++++++++++++++++++++++++++++++++++++---- 5 files changed, 74 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a07aad..4d29361 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,12 +138,6 @@ dependencies = [ "syn 2.0.89", ] -[[package]] -name = "bit-vec" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" - [[package]] name = "bit-vec" version = "0.8.0" @@ -462,7 +456,7 @@ dependencies = [ name = "dark_api" version = "0.0.0" dependencies = [ - "bit-vec 0.8.0", + "bit-vec", "cglue", "cuda_types", "format", @@ -2586,7 +2580,7 @@ dependencies = [ name = "ptx" version = "0.0.0" dependencies = [ - "bit-vec 0.6.3", + "bit-vec", "bitflags 1.3.2", "comgr", "cuda_macros", diff --git a/ptx/Cargo.toml b/ptx/Cargo.toml index 2f9b174..c9a5a6b 100644 --- a/ptx/Cargo.toml +++ b/ptx/Cargo.toml @@ -11,7 +11,7 @@ ptx_parser = { path = "../ptx_parser" } llvm_zluda = { path = "../llvm_zluda" } quick-error = "1.2" thiserror = "1.0" -bit-vec = "0.6" +bit-vec = "0.8" half ="1.6" bitflags = "1.2" rustc-hash = "2.0.0" diff --git a/ptx_parser/Cargo.toml b/ptx_parser/Cargo.toml index 3b96ac0..6f67e93 100644 --- a/ptx_parser/Cargo.toml +++ b/ptx_parser/Cargo.toml @@ -15,4 +15,4 @@ rustc-hash = "2.0.0" strum = { version = "0.27.1", features = ["derive"] } thiserror = "1.0" winnow = { version = "0.6.18" } -#winnow = { version = "0.6.18", features = ["debug"] } +# winnow = { version = "0.6.18", features = ["debug"] } diff --git a/ptx_parser/src/ast.rs b/ptx_parser/src/ast.rs index 3f14540..a58830e 100644 --- a/ptx_parser/src/ast.rs +++ b/ptx_parser/src/ast.rs @@ -1492,6 +1492,7 @@ pub enum Directive<'input, O: Operand> { pub struct Module<'input> { pub version: (u8, u8), pub directives: Vec>>, + pub invalid_directives: usize, } #[derive(Copy, Clone)] diff --git a/ptx_parser/src/lib.rs b/ptx_parser/src/lib.rs index 6e4e167..dd54a35 100644 --- a/ptx_parser/src/lib.rs +++ b/ptx_parser/src/lib.rs @@ -417,13 +417,16 @@ fn module<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult(stream: &mut &str) -> PResult<(u32, Option)> { fn directive<'a, 'input>( stream: &mut PtxParser<'a, 'input>, ) -> PResult>>> { - trace( + let errors = stream.state.errors.len(); + let directive = trace( "directive", with_recovery( alt(( @@ -488,7 +492,11 @@ fn directive<'a, 'input>( ) .map(Option::flatten), ) - .parse_next(stream) + .parse_next(stream)?; + if errors != stream.state.errors.len() { + return Ok(None); + } + Ok(directive) } fn module_variable<'a, 'input>( @@ -1266,6 +1274,25 @@ fn repeat_without_none>( ) } +fn repeat_without_none_and_count>( + parser: impl Parser, Error>, +) -> impl Parser, usize), Error> { + trace( + "repeat_without_none_and_count", + repeat(0.., parser).fold( + || (Vec::new(), 0), + |(mut accumulator, mut nones): (Vec<_>, usize), item| { + if let Some(item) = item { + accumulator.push(item); + } else { + nones += 1; + } + (accumulator, nones) + }, + ), + ) +} + fn ident_literal< 'a, 'input, @@ -3803,6 +3830,7 @@ derive_parser!( #[cfg(test)] mod tests { use crate::first_optional; + use crate::module; use crate::parse_module_checked; use crate::section; use crate::PtxError; @@ -4100,4 +4128,38 @@ mod tests { assert!(section.parse(stream).is_ok()); assert_eq!(errors.len(), 0); } + + #[test] + fn report_unknown_directives() { + let text = " + .version 6.5 + .target sm_30 + .address_size 64 + + .global .b32 global[4] = { unknown (1), 2, 3, 4}; + + .visible .entry func1() + { + st.u64 [out_addr], temp2; + ret; + } + + .visible .entry func1() + { + broken_instruction; + ret; + }"; + let tokens = Token::lexer(text) + .map(|t| t.map(|t| (t, Span::default()))) + .collect::, _>>() + .unwrap(); + let mut errors = Vec::new(); + let stream = super::PtxParser { + input: &tokens[..], + state: PtxParserState::new(text, &mut errors), + }; + let module = module.parse(stream).unwrap(); + assert_eq!(module.directives.len(), 1); + assert_eq!(module.invalid_directives, 2); + } }