mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 07:29:25 +02:00
Fix for Mantis #24687.
pgenutil.pas: + add new function could_be_generic which checks whether a given symbol name could be a generic (which is determined using the genericdummysyms list for the current module) pexpr.pas: * factor: only do a typecheck pass (postfixoperators does one as well) if the found node can not be a generic type * sub_expr: do a typecheck pass if it isn't a specialization + added test git-svn-id: trunk@25579 -
This commit is contained in:
parent
fb8b0e7a27
commit
e8edbd29c0
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -13585,6 +13585,7 @@ tests/webtbs/tw2483.pp svneol=native#text/plain
|
|||||||
tests/webtbs/tw24848.pp svneol=native#text/pascal
|
tests/webtbs/tw24848.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw24863.pp svneol=native#text/plain
|
tests/webtbs/tw24863.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw24865.pp svneol=native#text/pascal
|
tests/webtbs/tw24865.pp svneol=native#text/pascal
|
||||||
|
tests/webtbs/tw24867.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw24871.pp svneol=native#text/pascal
|
tests/webtbs/tw24871.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw2492.pp svneol=native#text/plain
|
tests/webtbs/tw2492.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2494.pp svneol=native#text/plain
|
tests/webtbs/tw2494.pp svneol=native#text/plain
|
||||||
|
@ -2825,12 +2825,15 @@ implementation
|
|||||||
hdef : tdef;
|
hdef : tdef;
|
||||||
filepos : tfileposinfo;
|
filepos : tfileposinfo;
|
||||||
callflags : tcallnodeflags;
|
callflags : tcallnodeflags;
|
||||||
|
idstr : tidstring;
|
||||||
|
dopostfix,
|
||||||
again,
|
again,
|
||||||
updatefpos,
|
updatefpos,
|
||||||
nodechanged : boolean;
|
nodechanged : boolean;
|
||||||
begin
|
begin
|
||||||
{ can't keep a copy of p1 and compare pointers afterwards, because
|
{ can't keep a copy of p1 and compare pointers afterwards, because
|
||||||
p1 may be freed and reallocated in the same place! }
|
p1 may be freed and reallocated in the same place! }
|
||||||
|
dopostfix:=true;
|
||||||
updatefpos:=false;
|
updatefpos:=false;
|
||||||
p1:=nil;
|
p1:=nil;
|
||||||
filepos:=current_tokenpos;
|
filepos:=current_tokenpos;
|
||||||
@ -2857,7 +2860,27 @@ implementation
|
|||||||
filepos:=current_tokenpos;
|
filepos:=current_tokenpos;
|
||||||
end;
|
end;
|
||||||
{ handle post fix operators }
|
{ handle post fix operators }
|
||||||
updatefpos:=postfixoperators(p1,again,getaddr);
|
if (m_delphi in current_settings.modeswitches) and
|
||||||
|
(block_type=bt_body) and
|
||||||
|
(token in [_LT,_LSHARPBRACKET]) then
|
||||||
|
begin
|
||||||
|
if p1.nodetype=typen then
|
||||||
|
idstr:=ttypenode(p1).typesym.name
|
||||||
|
else
|
||||||
|
if (p1.nodetype=loadvmtaddrn) and
|
||||||
|
(tloadvmtaddrnode(p1).left.nodetype=typen) then
|
||||||
|
idstr:=ttypenode(tloadvmtaddrnode(p1).left).typesym.name
|
||||||
|
else
|
||||||
|
if (p1.nodetype=loadn) then
|
||||||
|
idstr:=tloadnode(p1).symtableentry.name
|
||||||
|
else
|
||||||
|
idstr:='';
|
||||||
|
{ if this is the case then the postfix handling is done in
|
||||||
|
sub_expr if necessary }
|
||||||
|
dopostfix:=not could_be_generic(idstr);
|
||||||
|
end;
|
||||||
|
if dopostfix then
|
||||||
|
updatefpos:=postfixoperators(p1,again,getaddr);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -3327,8 +3350,8 @@ implementation
|
|||||||
updatefpos:=true;
|
updatefpos:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ get the resultdef for the node }
|
{ get the resultdef for the node if nothing stops us }
|
||||||
if (not assigned(p1.resultdef)) then
|
if (not assigned(p1.resultdef)) and dopostfix then
|
||||||
begin
|
begin
|
||||||
do_typecheckpass_changed(p1,nodechanged);
|
do_typecheckpass_changed(p1,nodechanged);
|
||||||
updatefpos:=updatefpos or nodechanged;
|
updatefpos:=updatefpos or nodechanged;
|
||||||
@ -3516,9 +3539,13 @@ implementation
|
|||||||
begin
|
begin
|
||||||
{ this is a normal "<" comparison }
|
{ this is a normal "<" comparison }
|
||||||
|
|
||||||
{ potential generic types that are followed by a "<" }
|
{ potential generic types that are followed by a "<": }
|
||||||
|
|
||||||
{ a) are not checked whether they are an undefined def,
|
{ a) might not have their resultdef set }
|
||||||
|
if not assigned(p1.resultdef) then
|
||||||
|
do_typecheckpass(p1);
|
||||||
|
|
||||||
|
{ b) are not checked whether they are an undefined def,
|
||||||
but not a generic parameter }
|
but not a generic parameter }
|
||||||
if (p1.nodetype=typen) and
|
if (p1.nodetype=typen) and
|
||||||
(ttypenode(p1).typedef.typ=undefineddef) and
|
(ttypenode(p1).typedef.typ=undefineddef) and
|
||||||
@ -3530,7 +3557,7 @@ implementation
|
|||||||
p1:=cerrornode.create;
|
p1:=cerrornode.create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ b) don't have their hints checked }
|
{ c) don't have their hints checked }
|
||||||
if istypenode(p1) then
|
if istypenode(p1) then
|
||||||
begin
|
begin
|
||||||
gendef:=gettypedef(p1);
|
gendef:=gettypedef(p1);
|
||||||
|
@ -43,6 +43,7 @@ uses
|
|||||||
function generate_generic_name(const name:tidstring;specializename:ansistring):tidstring;
|
function generate_generic_name(const name:tidstring;specializename:ansistring):tidstring;
|
||||||
procedure split_generic_name(const name:tidstring;out nongeneric:string;out count:longint);
|
procedure split_generic_name(const name:tidstring;out nongeneric:string;out count:longint);
|
||||||
function resolve_generic_dummysym(const name:tidstring):tsym;
|
function resolve_generic_dummysym(const name:tidstring):tsym;
|
||||||
|
function could_be_generic(const name:tidstring):boolean;inline;
|
||||||
|
|
||||||
type
|
type
|
||||||
tspecializationstate = record
|
tspecializationstate = record
|
||||||
@ -1137,6 +1138,12 @@ uses
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function could_be_generic(const name:tidstring):boolean;
|
||||||
|
begin
|
||||||
|
result:=(name<>'') and
|
||||||
|
(current_module.genericdummysyms.findindexof(name)>=0);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure specialization_init(genericdef:tdef;var state: tspecializationstate);
|
procedure specialization_init(genericdef:tdef;var state: tspecializationstate);
|
||||||
var
|
var
|
||||||
pu : tused_unit;
|
pu : tused_unit;
|
||||||
|
16
tests/webtbs/tw24867.pp
Normal file
16
tests/webtbs/tw24867.pp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{ %NORUN }
|
||||||
|
|
||||||
|
program tw24867;
|
||||||
|
|
||||||
|
{$MODE DELPHi}{$H+}
|
||||||
|
{$APPTYPE CONSOLE}
|
||||||
|
|
||||||
|
uses
|
||||||
|
fgl;
|
||||||
|
|
||||||
|
var
|
||||||
|
d: TFPGMap<string, string>; // ok
|
||||||
|
begin
|
||||||
|
d := TFPGMap<string, string>.Create; // Error: This type can't be a generic
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user