浏览代码

Disallow the usage of the inline assembler inside generics, because there are currently two problems:
1. At least on x86 the assembler reader initializes the parameter location informations which results in InternalError 200301231
2. Assembler tokens are not stored in the token stream and thus won't be reproduced during specialization

x86/rax86int.pas, tx86intreader.Assemble:
* check for "parse_generic" before calling generate_parameter_info
pstatmnt.pas, assembler_block & statement:
* generate an error message if an asm statement should be parsed inside a generic

+ added test

git-svn-id: trunk@24892 -

svenbarth 12 年之前
父节点
当前提交
b6bfa864d4
共有 7 个文件被更改,包括 429 次插入398 次删除
  1. 1 0
      .gitattributes
  2. 3 1
      compiler/msg/errore.msg
  3. 3 2
      compiler/msgidx.inc
  4. 392 392
      compiler/msgtxt.inc
  5. 8 1
      compiler/pstatmnt.pas
  6. 3 2
      compiler/x86/rax86int.pas
  7. 19 0
      tests/webtbf/tw24588.pp

+ 1 - 0
.gitattributes

@@ -12354,6 +12354,7 @@ tests/webtbf/tw24184.pp svneol=native#text/plain
 tests/webtbf/tw24428.pp svneol=native#text/plain
 tests/webtbf/tw24428a.pp svneol=native#text/plain
 tests/webtbf/tw24495.pp svneol=native#text/pascal
+tests/webtbf/tw24588.pp svneol=native#text/pascal
 tests/webtbf/tw2478.pp svneol=native#text/plain
 tests/webtbf/tw2562.pp svneol=native#text/plain
 tests/webtbf/tw2657.pp svneol=native#text/plain

+ 3 - 1
compiler/msg/errore.msg

@@ -398,7 +398,7 @@ scan_e_illegal_peoptflag=02094_E_Illegal argument for SETPEOPTFLAGS
 #
 # Parser
 #
-# 03333 is the last used one
+# 03334 is the last used one
 #
 % \section{Parser messages}
 % This section lists all parser messages. The parser takes care of the
@@ -1496,6 +1496,8 @@ parser_e_not_allowed_in_record=03332_E_Visibility section "$1" not allowed in re
 parser_e_proc_dir_not_allowed=03333_E_Procedure directive "$1" not allowed here
 % This procedure directive is not allowed in the given context. E.g. "static"
 % is not allowed for instance methods or class operators.
+parser_e_no_assembler_in_generic=03334_E_Assembler blocks not allowed inside generics
+% The use of assembler blocks/routines is not allowed inside generics.
 %
 %
 % \end{description}

+ 3 - 2
compiler/msgidx.inc

@@ -431,6 +431,7 @@ const
   parser_e_no_class_in_local_anonymous_records=03331;
   parser_e_not_allowed_in_record=03332;
   parser_e_proc_dir_not_allowed=03333;
+  parser_e_no_assembler_in_generic=03334;
   type_e_mismatch=04000;
   type_e_incompatible_types=04001;
   type_e_not_equal_types=04002;
@@ -975,9 +976,9 @@ const
   option_info=11024;
   option_help_pages=11025;
 
-  MsgTxtSize = 69070;
+  MsgTxtSize = 69135;
 
   MsgIdxMax : array[1..20] of longint=(
-    26,95,334,121,88,56,126,27,202,63,
+    26,95,335,121,88,56,126,27,202,63,
     54,20,1,1,1,1,1,1,1,1
   );

文件差异内容过多而无法显示
+ 392 - 392
compiler/msgtxt.inc


+ 8 - 1
compiler/pstatmnt.pas

@@ -1187,7 +1187,11 @@ implementation
                 code:=cnodeutils.call_fail_node;
              end;
            _ASM :
-             code:=_asm_statement;
+             begin
+               if parse_generic then
+                 Message(parser_e_no_assembler_in_generic);
+               code:=_asm_statement;
+             end;
            _EOF :
              Message(scan_f_end_of_file);
          else
@@ -1365,6 +1369,9 @@ implementation
 {$endif arm}
         srsym : tsym;
       begin
+         if parse_generic then
+           message(parser_e_no_assembler_in_generic);
+
          { Rename the funcret so that recursive calls are possible }
          if not is_void(current_procinfo.procdef.returndef) then
            begin

+ 3 - 2
compiler/x86/rax86int.pas

@@ -86,7 +86,7 @@ Unit Rax86int;
        { symtable }
        symconst,symbase,symtype,symsym,symdef,symtable,
        { parser }
-       scanner,
+       scanner,pbase,
        { register allocator }
        rabase,rautils,itx86int,
        { codegen }
@@ -2222,7 +2222,8 @@ Unit Rax86int;
       { setup label linked list }
       LocalLabelList:=TLocalLabelList.Create;
       { we might need to know which parameters are passed in registers }
-      current_procinfo.generate_parameter_info;
+      if not parse_generic then
+        current_procinfo.generate_parameter_info;
       { start tokenizer }
       c:=current_scanner.asmgetcharstart;
       gettoken;

+ 19 - 0
tests/webtbf/tw24588.pp

@@ -0,0 +1,19 @@
+{ %FAIL }
+program tw24588;
+{$mode objfpc}
+{$asmmode intel}
+type
+generic TFoo<T>=class
+procedure CrashMe(_val: T);
+end;
+
+procedure TFoo.CrashMe(_val: T);
+begin
+asm
+mov edi,edi
+end;
+end;
+
+begin
+end.
+

部分文件因为文件数量过多而无法显示