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 -
This commit is contained in:
svenbarth 2013-06-13 19:42:49 +00:00
parent caef53e63b
commit b6bfa864d4
7 changed files with 483 additions and 450 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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}

View File

@ -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
);

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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
tests/webtbf/tw24588.pp Normal file
View File

@ -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.