@@ -12,6 +12,7 @@ use rustc_span::{
1212 BytePos ,
1313} ;
1414use rustc_span:: { InnerSpan , Span } ;
15+ use rustc_target:: asm:: InlineAsmArch ;
1516
1617struct AsmArgs {
1718 templates : Vec < P < ast:: Expr > > ,
@@ -427,6 +428,65 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
427428
428429 let template_str = & template_str. as_str ( ) ;
429430 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+
430490 let mut parser = parse:: Parser :: new (
431491 template_str,
432492 str_style,
@@ -468,54 +528,6 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
468528 for piece in unverified_pieces {
469529 match piece {
470530 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- }
519531 template. push ( ast:: InlineAsmTemplatePiece :: String ( s. to_string ( ) ) )
520532 }
521533 parse:: Piece :: NextArgument ( arg) => {
@@ -682,3 +694,15 @@ pub fn expand_asm<'cx>(
682694 }
683695 }
684696}
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