Revert r31262. Not doing type checking on generics leads to strange warnings (e.g. because variables are not considered as written). I better deal with the compile time errors one at a time than the warnings.

The added test shows such a bogus warning (sadly the test suite can handle the occurence or absense of certain messages yet :/ )

git-svn-id: trunk@33324 -
This commit is contained in:
svenbarth 2016-03-24 20:58:04 +00:00
parent 56ae2d34b2
commit 35f8d5427f
4 changed files with 80 additions and 49 deletions

1
.gitattributes vendored
View File

@ -10874,6 +10874,7 @@ tests/tbs/tb0613.pp svneol=native#text/pascal
tests/tbs/tb0614.pp svneol=native#text/pascal
tests/tbs/tb0615.pp svneol=native#text/pascal
tests/tbs/tb0616.pp svneol=native#text/pascal
tests/tbs/tb0617.pp svneol=native#text/pascal
tests/tbs/tb205.pp svneol=native#text/plain
tests/tbs/tb610.pp svneol=native#text/pascal
tests/tbs/tb613.pp svneol=native#text/plain

View File

@ -1287,59 +1287,54 @@ implementation
if p.nodetype in [vecn,derefn,typeconvn,subscriptn,loadn] then
maybe_call_procvar(p,false);
{ additional checks make no sense in a generic definition }
if not(df_generic in current_procinfo.procdef.defoptions) then
{ blockn support because a read/write is changed into a blocknode
with a separate statement for each read/write operation (JM)
the same is true for val() if the third parameter is not 32 bit
goto nodes are created by the compiler for non local exit statements, so
include them as well
}
if not(p.nodetype in [nothingn,errorn,calln,ifn,assignn,breakn,inlinen,
continuen,labeln,blockn,exitn,goton]) or
((p.nodetype=inlinen) and
not is_void(p.resultdef)) or
((p.nodetype=calln) and
(assigned(tcallnode(p).procdefinition)) and
(tcallnode(p).procdefinition.proctypeoption=potype_operator)) then
Message(parser_e_illegal_expression);
if not assigned(p.resultdef) then
do_typecheckpass(p);
{ Specify that we don't use the value returned by the call.
This is used for :
- dispose of temp stack space
- dispose on FPU stack
- extended syntax checking }
if (p.nodetype=calln) then
begin
{ blockn support because a read/write is changed into a blocknode
with a separate statement for each read/write operation (JM)
the same is true for val() if the third parameter is not 32 bit
exclude(tcallnode(p).callnodeflags,cnf_return_value_used);
goto nodes are created by the compiler for non local exit statements, so
include them as well
}
if not(p.nodetype in [nothingn,errorn,calln,ifn,assignn,breakn,inlinen,
continuen,labeln,blockn,exitn,goton]) or
((p.nodetype=inlinen) and
not is_void(p.resultdef)) or
((p.nodetype=calln) and
(assigned(tcallnode(p).procdefinition)) and
(tcallnode(p).procdefinition.proctypeoption=potype_operator)) then
{ in $x- state, the function result must not be ignored }
if not(cs_extsyntax in current_settings.moduleswitches) and
not(is_void(p.resultdef)) and
{ can be nil in case there was an error in the expression }
assigned(tcallnode(p).procdefinition) and
{ allow constructor calls to drop the result if they are
called as instance methods instead of class methods }
not(
(tcallnode(p).procdefinition.proctypeoption=potype_constructor) and
is_class_or_object(tprocdef(tcallnode(p).procdefinition).struct) and
assigned(tcallnode(p).methodpointer) and
(tnode(tcallnode(p).methodpointer).resultdef.typ=objectdef)
) then
Message(parser_e_illegal_expression);
if not assigned(p.resultdef) then
do_typecheckpass(p);
{ Specify that we don't use the value returned by the call.
This is used for :
- dispose of temp stack space
- dispose on FPU stack
- extended syntax checking }
if (p.nodetype=calln) then
begin
exclude(tcallnode(p).callnodeflags,cnf_return_value_used);
{ in $x- state, the function result must not be ignored }
if not(cs_extsyntax in current_settings.moduleswitches) and
not(is_void(p.resultdef)) and
{ can be nil in case there was an error in the expression }
assigned(tcallnode(p).procdefinition) and
{ allow constructor calls to drop the result if they are
called as instance methods instead of class methods }
not(
(tcallnode(p).procdefinition.proctypeoption=potype_constructor) and
is_class_or_object(tprocdef(tcallnode(p).procdefinition).struct) and
assigned(tcallnode(p).methodpointer) and
(tnode(tcallnode(p).methodpointer).resultdef.typ=objectdef)
) then
Message(parser_e_illegal_expression);
end;
end;
code:=p;
end;
end;
if assigned(code) and
{ type checking makes no sense in a generic definition }
not(df_generic in current_procinfo.procdef.defoptions) then
if assigned(code) then
begin
typecheckpass(code);
code.fileinfo:=filepos;

View File

@ -1869,9 +1869,7 @@ implementation
entrypos:=code.fileinfo;
{ Finish type checking pass }
{ type checking makes no sense in a generic definition }
if not(df_generic in current_procinfo.procdef.defoptions) then
do_typecheckpass(code);
do_typecheckpass(code);
if assigned(procdef.parentfpinitblock) then
begin

37
tests/tbs/tb0617.pp Normal file
View File

@ -0,0 +1,37 @@
{ %NORUN }
program tb0617;
{$mode objfpc}
type
generic TGenericStructList<T> = class
public
function Remove(const Item: T): Integer;
procedure Delete(Index: Integer);
function IndexOf(const Item: T): Integer;
end;
function TGenericStructList.Remove(const Item: T): Integer;
begin
Result := IndexOf(Item);
{ for some reason, FPC 3.1.1 makes here incorrect warning:
castlegenericlists.pas(254,13) Warning: Function result variable does not seem to be initialized }
if Result >= 0 then
Delete(Result);
end;
function TGenericStructList.IndexOf(const Item: T): Integer;
begin
Result := 0;
end;
procedure TGenericStructList.Delete(Index: Integer);
begin
end;
begin
end.