mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 05:59:08 +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/tw24863.pp svneol=native#text/plain
|
||||
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/tw2492.pp svneol=native#text/plain
|
||||
tests/webtbs/tw2494.pp svneol=native#text/plain
|
||||
|
@ -2825,12 +2825,15 @@ implementation
|
||||
hdef : tdef;
|
||||
filepos : tfileposinfo;
|
||||
callflags : tcallnodeflags;
|
||||
idstr : tidstring;
|
||||
dopostfix,
|
||||
again,
|
||||
updatefpos,
|
||||
nodechanged : boolean;
|
||||
begin
|
||||
{ can't keep a copy of p1 and compare pointers afterwards, because
|
||||
p1 may be freed and reallocated in the same place! }
|
||||
dopostfix:=true;
|
||||
updatefpos:=false;
|
||||
p1:=nil;
|
||||
filepos:=current_tokenpos;
|
||||
@ -2857,7 +2860,27 @@ implementation
|
||||
filepos:=current_tokenpos;
|
||||
end;
|
||||
{ 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
|
||||
else
|
||||
begin
|
||||
@ -3327,8 +3350,8 @@ implementation
|
||||
updatefpos:=true;
|
||||
end;
|
||||
|
||||
{ get the resultdef for the node }
|
||||
if (not assigned(p1.resultdef)) then
|
||||
{ get the resultdef for the node if nothing stops us }
|
||||
if (not assigned(p1.resultdef)) and dopostfix then
|
||||
begin
|
||||
do_typecheckpass_changed(p1,nodechanged);
|
||||
updatefpos:=updatefpos or nodechanged;
|
||||
@ -3516,9 +3539,13 @@ implementation
|
||||
begin
|
||||
{ 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 }
|
||||
if (p1.nodetype=typen) and
|
||||
(ttypenode(p1).typedef.typ=undefineddef) and
|
||||
@ -3530,7 +3557,7 @@ implementation
|
||||
p1:=cerrornode.create;
|
||||
end;
|
||||
|
||||
{ b) don't have their hints checked }
|
||||
{ c) don't have their hints checked }
|
||||
if istypenode(p1) then
|
||||
begin
|
||||
gendef:=gettypedef(p1);
|
||||
|
@ -43,6 +43,7 @@ uses
|
||||
function generate_generic_name(const name:tidstring;specializename:ansistring):tidstring;
|
||||
procedure split_generic_name(const name:tidstring;out nongeneric:string;out count:longint);
|
||||
function resolve_generic_dummysym(const name:tidstring):tsym;
|
||||
function could_be_generic(const name:tidstring):boolean;inline;
|
||||
|
||||
type
|
||||
tspecializationstate = record
|
||||
@ -1137,6 +1138,12 @@ uses
|
||||
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);
|
||||
var
|
||||
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