diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2014-02-07 20:40:42 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2014-02-07 20:40:42 +0000 |
commit | 5378467b1eb7f7d01ad2ec4cf829455457e574ab (patch) | |
tree | 315d43c6eee4d71225867a4a76083a1663cf26f6 | |
parent | d438a751ba175857aa2a766a59b487bc258f7063 (diff) | |
download | fpc-5378467b1eb7f7d01ad2ec4cf829455457e574ab.tar.gz |
+ nf_addr_taken: it marks nodes which address is taken
+ check if tnodeflags is 4 bytes or less
* do not do cse on expressions which address is taken
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@26713 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | compiler/htypechk.pas | 2 | ||||
-rw-r--r-- | compiler/ncal.pas | 4 | ||||
-rw-r--r-- | compiler/node.pas | 7 | ||||
-rw-r--r-- | compiler/optcse.pas | 2 | ||||
-rw-r--r-- | compiler/optloop.pas | 2 | ||||
-rw-r--r-- | tests/tbs/tb0603.pp | 8 |
6 files changed, 20 insertions, 5 deletions
diff --git a/compiler/htypechk.pas b/compiler/htypechk.pas index 3a3ecf2146..b49734dfab 100644 --- a/compiler/htypechk.pas +++ b/compiler/htypechk.pas @@ -974,6 +974,8 @@ implementation { marks an lvalue as "unregable" } procedure make_not_regable_intern(p : tnode; how: tregableinfoflags; records_only: boolean); begin + if ra_addr_taken in how then + include(p.flags,nf_address_taken); repeat case p.nodetype of subscriptn: diff --git a/compiler/ncal.pas b/compiler/ncal.pas index c5f2d497df..661b5fac09 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -3748,7 +3748,7 @@ implementation begin temp:=paras.left.getcopy; { inherit modification information, this is needed by the dfa/cse } - temp.flags:=temp.flags+(n.flags*[nf_modify,nf_write]); + temp.flags:=temp.flags+(n.flags*[nf_modify,nf_write,nf_address_taken]); n.free; n:=temp; typecheckpass(n); @@ -3766,7 +3766,7 @@ implementation internalerror(20040720); temp := tnode(inlinelocals[indexnr]).getcopy; { inherit modification information, this is needed by the dfa/cse } - temp.flags:=temp.flags+(n.flags*[nf_modify,nf_write]); + temp.flags:=temp.flags+(n.flags*[nf_modify,nf_write,nf_address_taken]); n.free; n:=temp; typecheckpass(n); diff --git a/compiler/node.pas b/compiler/node.pas index 32e2d95492..337e2c7d71 100644 --- a/compiler/node.pas +++ b/compiler/node.pas @@ -219,6 +219,8 @@ interface nf_write, { Node is modified } nf_modify, + { address of node is taken } + nf_address_taken, nf_is_funcret, nf_isproperty, nf_processing, @@ -1317,9 +1319,12 @@ implementation begin {$push}{$warnings off} - { tvaroption should fit into a 4 byte set for speed reasons } + { tvaroption must fit into a 4 byte set for speed reasons } if ord(high(tvaroption))>31 then internalerror(201110301); + { tnodeflags must fit into a 4 byte set for speed reasons } + if ord(high(tnodeflags))>31 then + internalerror(2014020701); {$pop} end. diff --git a/compiler/optcse.pas b/compiler/optcse.pas index 089be5cda3..0634a213e7 100644 --- a/compiler/optcse.pas +++ b/compiler/optcse.pas @@ -151,7 +151,7 @@ unit optcse; assigned(n.resultdef) and ( { regable expressions } - (actualtargetnode(@n)^.flags*[nf_write,nf_modify]=[]) and + (actualtargetnode(@n)^.flags*[nf_write,nf_modify,nf_address_taken]=[]) and ((tstoreddef(n.resultdef).is_intregable or tstoreddef(n.resultdef).is_fpuregable) and { is_int/fpuregable allows arrays and records to be in registers, cse cannot handle this } (not(n.resultdef.typ in [arraydef,recorddef])) and diff --git a/compiler/optloop.pas b/compiler/optloop.pas index 0000b3048b..1d1f6662f1 100644 --- a/compiler/optloop.pas +++ b/compiler/optloop.pas @@ -86,7 +86,7 @@ unit optloop; ((n.nodetype=temprefn) and (preplaceinfo(arg)^.node.nodetype=temprefn) and (ttemprefnode(n).tempinfo=ttemprefnode(preplaceinfo(arg)^.node).tempinfo)) then begin - if n.flags*[nf_modify,nf_write]<>[] then + if n.flags*[nf_modify,nf_write,nf_address_taken]<>[] then internalerror(2012090402); n.free; n:=cordconstnode.create(preplaceinfo(arg)^.value,preplaceinfo(arg)^.node.resultdef,false); diff --git a/tests/tbs/tb0603.pp b/tests/tbs/tb0603.pp new file mode 100644 index 0000000000..adad454e08 --- /dev/null +++ b/tests/tbs/tb0603.pp @@ -0,0 +1,8 @@ +{ %OPT=-O3 } +{ %norun } +program test4; +var + S : ansistring; +begin + writeln((PByte(@S[1])^ = $1) or (S[1] = '.')); +end. |