@@ -12,6 +12,7 @@ use rustc_span::{
12
12
BytePos ,
13
13
} ;
14
14
use rustc_span:: { InnerSpan , Span } ;
15
+ use rustc_target:: asm:: InlineAsmArch ;
15
16
16
17
struct AsmArgs {
17
18
templates : Vec < P < ast:: Expr > > ,
@@ -427,6 +428,65 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
427
428
428
429
let template_str = & template_str. as_str ( ) ;
429
430
let template_snippet = ecx. source_map ( ) . span_to_snippet ( template_sp) . ok ( ) ;
431
+
432
+ if let Some ( snippet) = & template_snippet {
433
+ let default_dialect = match ecx. sess . asm_arch {
434
+ Some ( InlineAsmArch :: X86 | InlineAsmArch :: X86_64 ) => ast:: LlvmAsmDialect :: Intel ,
435
+ _ => ast:: LlvmAsmDialect :: Att ,
436
+ } ;
437
+
438
+ let snippet = snippet. trim_matches ( '"' ) ;
439
+ match default_dialect {
440
+ ast:: LlvmAsmDialect :: Intel => {
441
+ if let Some ( span) = check_syntax_directive ( snippet, ".intel_syntax" ) {
442
+ let span = template_span. from_inner ( span) ;
443
+ let mut err = ecx. struct_span_err ( span, "intel syntax is the default syntax on this target, and trying to use this directive may cause issues" ) ;
444
+ err. span_suggestion (
445
+ span,
446
+ "remove this assembler directive" ,
447
+ "" . to_string ( ) ,
448
+ Applicability :: MachineApplicable ,
449
+ ) ;
450
+ err. emit ( ) ;
451
+ }
452
+
453
+ if let Some ( span) = check_syntax_directive ( snippet, ".att_syntax" ) {
454
+ let span = template_span. from_inner ( span) ;
455
+ let mut err = ecx. struct_span_err ( span, "using the .att_syntax directive may cause issues, use the att_syntax option instead" ) ;
456
+ let asm_end = sp. hi ( ) - BytePos ( 2 ) ;
457
+ let suggestions = vec ! [
458
+ ( span, "" . to_string( ) ) ,
459
+ (
460
+ Span :: new( asm_end, asm_end, sp. ctxt( ) ) ,
461
+ ", options(att_syntax)" . to_string( ) ,
462
+ ) ,
463
+ ] ;
464
+ err. multipart_suggestion (
465
+ "remove the assembler directive and replace it with options(att_syntax)" ,
466
+ suggestions,
467
+ Applicability :: MachineApplicable ,
468
+ ) ;
469
+ err. emit ( ) ;
470
+ }
471
+ }
472
+ ast:: LlvmAsmDialect :: Att => {
473
+ if let Some ( span) = check_syntax_directive ( snippet, ".att_syntax" ) {
474
+ let span = template_span. from_inner ( span) ;
475
+ let mut err = ecx. struct_span_err ( span, "att syntax is the default syntax on this target, and trying to use this directive may cause issues" ) ;
476
+ err. span_suggestion (
477
+ span,
478
+ "remove this assembler directive" ,
479
+ "" . to_string ( ) ,
480
+ Applicability :: MachineApplicable ,
481
+ ) ;
482
+ err. emit ( ) ;
483
+ }
484
+
485
+ // Use of .intel_syntax is ignored
486
+ }
487
+ }
488
+ }
489
+
430
490
let mut parser = parse:: Parser :: new (
431
491
template_str,
432
492
str_style,
@@ -468,54 +528,6 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
468
528
for piece in unverified_pieces {
469
529
match piece {
470
530
parse:: Piece :: String ( s) => {
471
- if let Some ( idx) = s. find ( ".intel_syntax" ) {
472
- let mut end = idx + ".intel_syntax" . len ( ) ;
473
- if let Some ( prefix_idx) = s. split_at ( end) . 1 . find ( "noprefix" ) {
474
- // Should be a space and it should be immediately after
475
- if prefix_idx == 1 {
476
- end += " noprefix" . len ( ) ;
477
- }
478
- }
479
-
480
- let syntax_span =
481
- template_span. from_inner ( InnerSpan :: new ( idx + 1 , end + 1 ) ) ;
482
- let mut err = ecx. struct_span_err ( syntax_span, "intel sytnax is the default syntax, and trying to use this directive may cause issues" ) ;
483
- err. span_suggestion (
484
- syntax_span,
485
- "Remove this assembler directive" ,
486
- s. replace ( & s[ idx..end] , "" ) . to_string ( ) ,
487
- Applicability :: MachineApplicable ,
488
- ) ;
489
- err. emit ( ) ;
490
- }
491
-
492
- if let Some ( idx) = s. find ( ".att_syntax" ) {
493
- let mut end = idx + ".att_syntax" . len ( ) ;
494
- if let Some ( prefix_idx) = s. split_at ( end) . 1 . find ( "noprefix" ) {
495
- // Should be a space and it should be immediately after
496
- if prefix_idx == 1 {
497
- end += " noprefix" . len ( ) ;
498
- }
499
- }
500
-
501
- let syntax_span =
502
- template_span. from_inner ( InnerSpan :: new ( idx + 1 , end + 1 ) ) ;
503
- let mut err = ecx. struct_span_err ( syntax_span, "using the .att_syntax directive may cause issues, use the att_syntax option instead" ) ;
504
- let asm_end = sp. hi ( ) - BytePos ( 2 ) ;
505
- let suggestions = vec ! [
506
- ( syntax_span, "" . to_string( ) ) ,
507
- (
508
- Span :: new( asm_end, asm_end, sp. ctxt( ) ) ,
509
- ", options(att_syntax)" . to_string( ) ,
510
- ) ,
511
- ] ;
512
- err. multipart_suggestion (
513
- "Remove the assembler directive and replace it with options(att_syntax)" ,
514
- suggestions,
515
- Applicability :: MachineApplicable ,
516
- ) ;
517
- err. emit ( ) ;
518
- }
519
531
template. push ( ast:: InlineAsmTemplatePiece :: String ( s. to_string ( ) ) )
520
532
}
521
533
parse:: Piece :: NextArgument ( arg) => {
@@ -682,3 +694,15 @@ pub fn expand_asm<'cx>(
682
694
}
683
695
}
684
696
}
697
+
698
+ fn check_syntax_directive < S : AsRef < str > > ( piece : S , syntax : & str ) -> Option < InnerSpan > {
699
+ let piece = piece. as_ref ( ) ;
700
+ if let Some ( idx) = piece. find ( syntax) {
701
+ let end =
702
+ idx + & piece[ idx..] . find ( |c| matches ! ( c, '\n' | ';' ) ) . unwrap_or ( piece[ idx..] . len ( ) ) ;
703
+ // Offset by one because these represent the span with the " removed
704
+ Some ( InnerSpan :: new ( idx + 1 , end + 1 ) )
705
+ } else {
706
+ None
707
+ }
708
+ }
0 commit comments