mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 03:46:10 +02:00
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:
parent
56ae2d34b2
commit
35f8d5427f
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -10874,6 +10874,7 @@ tests/tbs/tb0613.pp svneol=native#text/pascal
|
|||||||
tests/tbs/tb0614.pp svneol=native#text/pascal
|
tests/tbs/tb0614.pp svneol=native#text/pascal
|
||||||
tests/tbs/tb0615.pp svneol=native#text/pascal
|
tests/tbs/tb0615.pp svneol=native#text/pascal
|
||||||
tests/tbs/tb0616.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/tb205.pp svneol=native#text/plain
|
||||||
tests/tbs/tb610.pp svneol=native#text/pascal
|
tests/tbs/tb610.pp svneol=native#text/pascal
|
||||||
tests/tbs/tb613.pp svneol=native#text/plain
|
tests/tbs/tb613.pp svneol=native#text/plain
|
||||||
|
@ -1287,59 +1287,54 @@ implementation
|
|||||||
if p.nodetype in [vecn,derefn,typeconvn,subscriptn,loadn] then
|
if p.nodetype in [vecn,derefn,typeconvn,subscriptn,loadn] then
|
||||||
maybe_call_procvar(p,false);
|
maybe_call_procvar(p,false);
|
||||||
|
|
||||||
{ additional checks make no sense in a generic definition }
|
{ blockn support because a read/write is changed into a blocknode
|
||||||
if not(df_generic in current_procinfo.procdef.defoptions) then
|
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
|
begin
|
||||||
{ blockn support because a read/write is changed into a blocknode
|
exclude(tcallnode(p).callnodeflags,cnf_return_value_used);
|
||||||
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
|
{ in $x- state, the function result must not be ignored }
|
||||||
include them as well
|
if not(cs_extsyntax in current_settings.moduleswitches) and
|
||||||
}
|
not(is_void(p.resultdef)) and
|
||||||
if not(p.nodetype in [nothingn,errorn,calln,ifn,assignn,breakn,inlinen,
|
{ can be nil in case there was an error in the expression }
|
||||||
continuen,labeln,blockn,exitn,goton]) or
|
assigned(tcallnode(p).procdefinition) and
|
||||||
((p.nodetype=inlinen) and
|
{ allow constructor calls to drop the result if they are
|
||||||
not is_void(p.resultdef)) or
|
called as instance methods instead of class methods }
|
||||||
((p.nodetype=calln) and
|
not(
|
||||||
(assigned(tcallnode(p).procdefinition)) and
|
(tcallnode(p).procdefinition.proctypeoption=potype_constructor) and
|
||||||
(tcallnode(p).procdefinition.proctypeoption=potype_operator)) then
|
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);
|
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;
|
end;
|
||||||
|
|
||||||
code:=p;
|
code:=p;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if assigned(code) and
|
if assigned(code) then
|
||||||
{ type checking makes no sense in a generic definition }
|
|
||||||
not(df_generic in current_procinfo.procdef.defoptions) then
|
|
||||||
begin
|
begin
|
||||||
typecheckpass(code);
|
typecheckpass(code);
|
||||||
code.fileinfo:=filepos;
|
code.fileinfo:=filepos;
|
||||||
|
@ -1869,9 +1869,7 @@ implementation
|
|||||||
entrypos:=code.fileinfo;
|
entrypos:=code.fileinfo;
|
||||||
|
|
||||||
{ Finish type checking pass }
|
{ Finish type checking pass }
|
||||||
{ type checking makes no sense in a generic definition }
|
do_typecheckpass(code);
|
||||||
if not(df_generic in current_procinfo.procdef.defoptions) then
|
|
||||||
do_typecheckpass(code);
|
|
||||||
|
|
||||||
if assigned(procdef.parentfpinitblock) then
|
if assigned(procdef.parentfpinitblock) then
|
||||||
begin
|
begin
|
||||||
|
37
tests/tbs/tb0617.pp
Normal file
37
tests/tbs/tb0617.pp
Normal 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.
|
Loading…
Reference in New Issue
Block a user