浏览代码

+ take care of asmmode in $push/$pop, resolves #41190

florian 4 月之前
父节点
当前提交
eb5c61281c
共有 5 个文件被更改,包括 60 次插入5 次删除
  1. 3 1
      compiler/globals.pas
  2. 7 1
      compiler/pstatmnt.pas
  3. 13 3
      compiler/scandir.pas
  4. 13 0
      compiler/switches.pas
  5. 24 0
      tests/webtbs/tw41190.pp

+ 3 - 1
compiler/globals.pas

@@ -260,7 +260,8 @@ Const
         psf_local_switches_changed,
         psf_local_switches_changed,
         psf_packenum_changed,
         psf_packenum_changed,
         psf_packrecords_changed,
         psf_packrecords_changed,
-        psf_setalloc_changed
+        psf_setalloc_changed,
+        psf_asmmode_changed
       );
       );
       tpendingstateflags = set of tpendingstateflag;
       tpendingstateflags = set of tpendingstateflag;
 
 
@@ -274,6 +275,7 @@ Const
         nextpackenum : shortint;
         nextpackenum : shortint;
         nextpackrecords : shortint;
         nextpackrecords : shortint;
         nextsetalloc : shortint;
         nextsetalloc : shortint;
+        nextasmmode : tasmmode;
         flags : tpendingstateflags;
         flags : tpendingstateflags;
       end;
       end;
 
 

+ 7 - 1
compiler/pstatmnt.pas

@@ -57,7 +57,9 @@ implementation
        { codegen }
        { codegen }
        procinfo,cgbase,
        procinfo,cgbase,
        { assembler reader }
        { assembler reader }
-       rabase;
+       rabase,
+       { scanner }
+       switches;
 
 
 
 
     function statement : tnode;forward;
     function statement : tnode;forward;
@@ -1067,6 +1069,10 @@ implementation
          Inside_asm_statement:=true;
          Inside_asm_statement:=true;
          asmstat:=nil;
          asmstat:=nil;
          hl:=nil;
          hl:=nil;
+
+         { apply all switch changes as the assembler readers doesn't do so }
+         flushpendingswitchesstate;
+
          if assigned(asmmodeinfos[current_settings.asmmode]) then
          if assigned(asmmodeinfos[current_settings.asmmode]) then
            begin
            begin
              asmreader:=asmmodeinfos[current_settings.asmmode]^.casmreader.create;
              asmreader:=asmmodeinfos[current_settings.asmmode]^.casmreader.create;

+ 13 - 3
compiler/scandir.pas

@@ -41,6 +41,7 @@ unit scandir;
         setalloc,
         setalloc,
         packenum,
         packenum,
         packrecords : shortint;
         packrecords : shortint;
+        asmmode : tasmmode;
       end;
       end;
 
 
     type
     type
@@ -312,16 +313,19 @@ unit scandir;
     procedure dir_asmmode;
     procedure dir_asmmode;
       var
       var
         s : string;
         s : string;
+        asmmode: tasmmode;
       begin
       begin
         current_scanner.skipspace;
         current_scanner.skipspace;
         s:=current_scanner.readid;
         s:=current_scanner.readid;
         If Inside_asm_statement then
         If Inside_asm_statement then
           Message1(scan_w_no_asm_reader_switch_inside_asm,s);
           Message1(scan_w_no_asm_reader_switch_inside_asm,s);
         if s='DEFAULT' then
         if s='DEFAULT' then
-         current_settings.asmmode:=init_settings.asmmode
+          recordpendingasmmode(init_settings.asmmode)
         else
         else
-         if not SetAsmReadMode(s,current_settings.asmmode) then
-           Message1(scan_e_illegal_asmmode_specifier,s);
+         if not SetAsmReadMode(s,asmmode) then
+           Message1(scan_e_illegal_asmmode_specifier,s)
+         else
+           recordpendingasmmode(asmmode);
       end;
       end;
 
 
 {$if defined(m68k) or defined(arm)}
 {$if defined(m68k) or defined(arm)}
@@ -1263,6 +1267,7 @@ unit scandir;
           recordpendingpackenum(switchesstatestack[switchesstatestackpos].packenum);
           recordpendingpackenum(switchesstatestack[switchesstatestackpos].packenum);
           recordpendingpackrecords(switchesstatestack[switchesstatestackpos].packrecords);
           recordpendingpackrecords(switchesstatestack[switchesstatestackpos].packrecords);
           recordpendingsetalloc(switchesstatestack[switchesstatestackpos].setalloc);
           recordpendingsetalloc(switchesstatestack[switchesstatestackpos].setalloc);
+          recordpendingasmmode(switchesstatestack[switchesstatestackpos].asmmode);
           pendingstate.nextmessagerecord:=switchesstatestack[switchesstatestackpos].pmessage;
           pendingstate.nextmessagerecord:=switchesstatestack[switchesstatestackpos].pmessage;
           { flushpendingswitchesstate will reset the message state }
           { flushpendingswitchesstate will reset the message state }
           current_settings.pmessage:=nil;
           current_settings.pmessage:=nil;
@@ -1327,6 +1332,11 @@ unit scandir;
       else
       else
         switchesstatestack[switchesstatestackpos].setalloc:=current_settings.setalloc;
         switchesstatestack[switchesstatestackpos].setalloc:=current_settings.setalloc;
 
 
+      if psf_asmmode_changed in pendingstate.flags then
+        switchesstatestack[switchesstatestackpos].asmmode:=pendingstate.nextasmmode
+      else
+        switchesstatestack[switchesstatestackpos].asmmode:=current_settings.asmmode;
+
       switchesstatestack[switchesstatestackpos].pmessage:=pendingstate.nextmessagerecord;
       switchesstatestack[switchesstatestackpos].pmessage:=pendingstate.nextmessagerecord;
       Inc(switchesstatestackpos);
       Inc(switchesstatestackpos);
     end;
     end;

+ 13 - 0
compiler/switches.pas

@@ -41,6 +41,7 @@ procedure recordpendingalignmentfullswitch(const alignment : talignmentinfo);
 procedure recordpendingsetalloc(alloc:shortint);
 procedure recordpendingsetalloc(alloc:shortint);
 procedure recordpendingpackenum(size:shortint);
 procedure recordpendingpackenum(size:shortint);
 procedure recordpendingpackrecords(size:shortint);
 procedure recordpendingpackrecords(size:shortint);
+procedure recordpendingasmmode(asmmode:tasmmode);
 procedure flushpendingswitchesstate;
 procedure flushpendingswitchesstate;
 
 
 implementation
 implementation
@@ -366,6 +367,13 @@ procedure recordpendingsetalloc(alloc:shortint);
   end;
   end;
 
 
 
 
+procedure recordpendingasmmode(asmmode:tasmmode);
+  begin
+    pendingstate.nextasmmode:=asmmode;
+    include(pendingstate.flags,psf_asmmode_changed);
+  end;
+
+
 procedure recordpendingpackenum(size:shortint);
 procedure recordpendingpackenum(size:shortint);
   begin
   begin
     pendingstate.nextpackenum:=size;
     pendingstate.nextpackenum:=size;
@@ -419,6 +427,11 @@ procedure flushpendingswitchesstate;
         current_settings.setalloc:=pendingstate.nextsetalloc;
         current_settings.setalloc:=pendingstate.nextsetalloc;
         exclude(pendingstate.flags,psf_setalloc_changed);
         exclude(pendingstate.flags,psf_setalloc_changed);
       end;
       end;
+    if psf_asmmode_changed in pendingstate.flags then
+      begin
+        current_settings.asmmode:=pendingstate.nextasmmode;
+        exclude(pendingstate.flags,psf_asmmode_changed);
+      end;
     { process pending verbosity changes (warnings on, etc) }
     { process pending verbosity changes (warnings on, etc) }
     if pendingstate.nextverbositystr<>'' then
     if pendingstate.nextverbositystr<>'' then
       begin
       begin

+ 24 - 0
tests/webtbs/tw41190.pp

@@ -0,0 +1,24 @@
+{ %cpu=x86_64 }
+program test;
+{$mode objfpc}
+
+//{$define INTEL}
+
+{$IFDEF INTEL}
+  {$asmmode intel}
+  {$push}{$asmmode att}{$pop}
+  procedure proc2; assembler;
+  asm
+    mov rax, 0 // err
+  end;
+{$ELSE}
+  {$asmmode att}
+  {$push}{$asmmode intel}{$pop}
+  procedure proc2; assembler;
+  asm
+    movq $0, %rax // err
+  end;
+{$ENDIF}
+
+begin
+end.