From e8edbd29c00eaa6d6744660add8c3d06c7c90ba8 Mon Sep 17 00:00:00 2001 From: svenbarth Date: Thu, 26 Sep 2013 10:21:11 +0000 Subject: [PATCH] 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 - --- .gitattributes | 1 + compiler/pexpr.pas | 39 +++++++++++++++++++++++++++++++++------ compiler/pgenutil.pas | 7 +++++++ tests/webtbs/tw24867.pp | 16 ++++++++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 tests/webtbs/tw24867.pp diff --git a/.gitattributes b/.gitattributes index d34971c7e6..d42d1c0d17 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas index b56fc6f05a..58787389fe 100644 --- a/compiler/pexpr.pas +++ b/compiler/pexpr.pas @@ -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); diff --git a/compiler/pgenutil.pas b/compiler/pgenutil.pas index 9f73dd46b6..7b3c9f09a0 100644 --- a/compiler/pgenutil.pas +++ b/compiler/pgenutil.pas @@ -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; diff --git a/tests/webtbs/tw24867.pp b/tests/webtbs/tw24867.pp new file mode 100644 index 0000000000..2f424dfcb6 --- /dev/null +++ b/tests/webtbs/tw24867.pp @@ -0,0 +1,16 @@ +{ %NORUN } + +program tw24867; + +{$MODE DELPHi}{$H+} +{$APPTYPE CONSOLE} + +uses + fgl; + +var + d: TFPGMap; // ok +begin + d := TFPGMap.Create; // Error: This type can't be a generic +end. +