@@ -2880,29 +2880,56 @@ enum AsmLabelKind {
28802880/// These follow the pattern: `[letter][digit(s)]:[digit(s)][optional_suffix]`
28812881///
28822882/// Returns `true` if the string matches a valid Hexagon register span pattern.
2883- fn is_hexagon_register_span ( possible_label : & str ) -> bool {
2884- if possible_label. len ( ) < 3 {
2883+ pub fn is_hexagon_register_span ( possible_label : & str ) -> bool {
2884+ // Extract the full register span from the context
2885+ if let Some ( colon_idx) = possible_label. find ( ':' ) {
2886+ let after_colon = & possible_label[ colon_idx + 1 ..] ;
2887+ is_hexagon_register_span_impl ( & possible_label[ ..colon_idx] , after_colon)
2888+ } else {
2889+ false
2890+ }
2891+ }
2892+
2893+ /// Helper function for use within the lint when we have statement context.
2894+ fn is_hexagon_register_span_context (
2895+ possible_label : & str ,
2896+ statement : & str ,
2897+ colon_idx : usize ,
2898+ ) -> bool {
2899+ // Extract what comes after the colon in the statement
2900+ let after_colon_start = colon_idx + 1 ;
2901+ if after_colon_start >= statement. len ( ) {
28852902 return false ;
28862903 }
28872904
2888- let mut chars = possible_label. chars ( ) ;
2905+ // Get the part after the colon, up to the next whitespace or special character
2906+ let after_colon_full = & statement[ after_colon_start..] ;
2907+ let after_colon = after_colon_full
2908+ . chars ( )
2909+ . take_while ( |& c| c. is_ascii_alphanumeric ( ) || c == '.' )
2910+ . collect :: < String > ( ) ;
2911+
2912+ is_hexagon_register_span_impl ( possible_label, & after_colon)
2913+ }
2914+
2915+ /// Core implementation for checking hexagon register spans.
2916+ fn is_hexagon_register_span_impl ( before_colon : & str , after_colon : & str ) -> bool {
2917+ if before_colon. len ( ) < 1 || after_colon. is_empty ( ) {
2918+ return false ;
2919+ }
2920+
2921+ let mut chars = before_colon. chars ( ) ;
28892922 let start = chars. next ( ) . unwrap ( ) ;
28902923
28912924 // Must start with a letter (r, V, p, etc.)
28922925 if !start. is_ascii_alphabetic ( ) {
28932926 return false ;
28942927 }
28952928
2896- let rest = & possible_label[ 1 ..] ;
2897- let Some ( colon_idx) = rest. find ( ':' ) else {
2898- return false ;
2899- } ;
2900-
2901- let ( before_colon, after_colon_with_colon) = rest. split_at ( colon_idx) ;
2902- let after_colon = & after_colon_with_colon[ 1 ..] ; // Skip the ':'
2929+ let rest = & before_colon[ 1 ..] ;
29032930
2904- // Check if before colon is all digits and non-empty
2905- if before_colon . is_empty ( ) || !before_colon . chars ( ) . all ( |c| c. is_ascii_digit ( ) ) {
2931+ // Check if the part after the first letter is all digits and non-empty
2932+ if rest . is_empty ( ) || !rest . chars ( ) . all ( |c| c. is_ascii_digit ( ) ) {
29062933 return false ;
29072934 }
29082935
@@ -2912,39 +2939,6 @@ fn is_hexagon_register_span(possible_label: &str) -> bool {
29122939 !digits_after. is_empty ( )
29132940}
29142941
2915- #[ cfg( test) ]
2916- mod tests {
2917- use super :: is_hexagon_register_span;
2918-
2919- #[ test]
2920- fn test_hexagon_register_span_patterns ( ) {
2921- // Valid Hexagon register span patterns
2922- assert ! ( is_hexagon_register_span( "r1:0" ) ) ;
2923- assert ! ( is_hexagon_register_span( "r15:14" ) ) ;
2924- assert ! ( is_hexagon_register_span( "V5:4" ) ) ;
2925- assert ! ( is_hexagon_register_span( "V3:2" ) ) ;
2926- assert ! ( is_hexagon_register_span( "V5:4.w" ) ) ;
2927- assert ! ( is_hexagon_register_span( "V3:2.h" ) ) ;
2928- assert ! ( is_hexagon_register_span( "p1:0" ) ) ;
2929- assert ! ( is_hexagon_register_span( "p3:2" ) ) ;
2930- assert ! ( is_hexagon_register_span( "r99:98" ) ) ;
2931- assert ! ( is_hexagon_register_span( "V123:122.whatever" ) ) ;
2932-
2933- // Invalid patterns - these should be treated as potential labels
2934- assert ! ( !is_hexagon_register_span( "label1" ) ) ;
2935- assert ! ( !is_hexagon_register_span( "foo:" ) ) ;
2936- assert ! ( !is_hexagon_register_span( ":0" ) ) ;
2937- assert ! ( !is_hexagon_register_span( "r:0" ) ) ; // missing digits before colon
2938- assert ! ( !is_hexagon_register_span( "r1:" ) ) ; // missing digits after colon
2939- assert ! ( !is_hexagon_register_span( "r1:a" ) ) ; // non-digit after colon
2940- assert ! ( !is_hexagon_register_span( "1:0" ) ) ; // starts with digit, not letter
2941- assert ! ( !is_hexagon_register_span( "r1" ) ) ; // no colon
2942- assert ! ( !is_hexagon_register_span( "r" ) ) ; // too short
2943- assert ! ( !is_hexagon_register_span( "" ) ) ; // empty
2944- assert ! ( !is_hexagon_register_span( "ra:0" ) ) ; // letter in first digit group
2945- }
2946- }
2947-
29482942impl < ' tcx > LateLintPass < ' tcx > for AsmLabels {
29492943 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx hir:: Expr < ' tcx > ) {
29502944 if let hir:: Expr {
@@ -3030,7 +3024,7 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels {
30303024 // Check for Hexagon register span notation (e.g., "r1:0", "V5:4", "V3:2.w")
30313025 // This is valid Hexagon assembly syntax, not a label
30323026 if matches ! ( cx. tcx. sess. asm_arch, Some ( InlineAsmArch :: Hexagon ) )
3033- && is_hexagon_register_span ( possible_label)
3027+ && is_hexagon_register_span_context ( possible_label, statement , idx )
30343028 {
30353029 break ' label_loop;
30363030 }
0 commit comments