@@ -2875,6 +2875,71 @@ enum AsmLabelKind {
28752875 Binary ,
28762876}
28772877
2878+ /// Checks if a potential label is actually a Hexagon register span notation.
2879+ ///
2880+ /// Hexagon assembly uses register span notation like `r1:0`, `V5:4.w`, `p1:0` etc.
2881+ /// These follow the pattern: `[letter][digit(s)]:[digit(s)][optional_suffix]`
2882+ ///
2883+ /// Returns `true` if the string matches a valid Hexagon register span pattern.
2884+ pub fn is_hexagon_register_span ( possible_label : & str ) -> bool {
2885+ // Extract the full register span from the context
2886+ if let Some ( colon_idx) = possible_label. find ( ':' ) {
2887+ let after_colon = & possible_label[ colon_idx + 1 ..] ;
2888+ is_hexagon_register_span_impl ( & possible_label[ ..colon_idx] , after_colon)
2889+ } else {
2890+ false
2891+ }
2892+ }
2893+
2894+ /// Helper function for use within the lint when we have statement context.
2895+ fn is_hexagon_register_span_context (
2896+ possible_label : & str ,
2897+ statement : & str ,
2898+ colon_idx : usize ,
2899+ ) -> bool {
2900+ // Extract what comes after the colon in the statement
2901+ let after_colon_start = colon_idx + 1 ;
2902+ if after_colon_start >= statement. len ( ) {
2903+ return false ;
2904+ }
2905+
2906+ // Get the part after the colon, up to the next whitespace or special character
2907+ let after_colon_full = & statement[ after_colon_start..] ;
2908+ let after_colon = after_colon_full
2909+ . chars ( )
2910+ . take_while ( |& c| c. is_ascii_alphanumeric ( ) || c == '.' )
2911+ . collect :: < String > ( ) ;
2912+
2913+ is_hexagon_register_span_impl ( possible_label, & after_colon)
2914+ }
2915+
2916+ /// Core implementation for checking hexagon register spans.
2917+ fn is_hexagon_register_span_impl ( before_colon : & str , after_colon : & str ) -> bool {
2918+ if before_colon. len ( ) < 1 || after_colon. is_empty ( ) {
2919+ return false ;
2920+ }
2921+
2922+ let mut chars = before_colon. chars ( ) ;
2923+ let start = chars. next ( ) . unwrap ( ) ;
2924+
2925+ // Must start with a letter (r, V, p, etc.)
2926+ if !start. is_ascii_alphabetic ( ) {
2927+ return false ;
2928+ }
2929+
2930+ let rest = & before_colon[ 1 ..] ;
2931+
2932+ // Check if the part after the first letter is all digits and non-empty
2933+ if rest. is_empty ( ) || !rest. chars ( ) . all ( |c| c. is_ascii_digit ( ) ) {
2934+ return false ;
2935+ }
2936+
2937+ // Check if after colon starts with digits (may have suffix like .w, .h)
2938+ let digits_after = after_colon. chars ( ) . take_while ( |c| c. is_ascii_digit ( ) ) . collect :: < String > ( ) ;
2939+
2940+ !digits_after. is_empty ( )
2941+ }
2942+
28782943impl < ' tcx > LateLintPass < ' tcx > for AsmLabels {
28792944 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx hir:: Expr < ' tcx > ) {
28802945 if let hir:: Expr {
@@ -2957,6 +3022,14 @@ impl<'tcx> LateLintPass<'tcx> for AsmLabels {
29573022 break ' label_loop;
29583023 }
29593024
3025+ // Check for Hexagon register span notation (e.g., "r1:0", "V5:4", "V3:2.w")
3026+ // This is valid Hexagon assembly syntax, not a label
3027+ if matches ! ( cx. tcx. sess. asm_arch, Some ( InlineAsmArch :: Hexagon ) )
3028+ && is_hexagon_register_span_context ( possible_label, statement, idx)
3029+ {
3030+ break ' label_loop;
3031+ }
3032+
29603033 for c in chars {
29613034 // Inside a template format arg, any character is permitted for the
29623035 // purposes of label detection because we assume that it can be
0 commit comments