From 857664a5d479fe71a830f3e6a6a707d1a3e2bb89 Mon Sep 17 00:00:00 2001 From: Jonas Maebe <jonas@freepascal.org> Date: Fri, 23 Dec 2005 21:08:48 +0000 Subject: [PATCH] * fixed tw4554: * proper uninitialized checking for arrays * first check uninitialized status of right side of assignment before setting the left side to "written" (-> catch "x:=x" if x is uninitialized) git-svn-id: trunk@2038 - --- compiler/htypechk.pas | 7 +++++-- compiler/nld.pas | 2 +- compiler/nmem.pas | 22 +++++++++++++++------- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/compiler/htypechk.pas b/compiler/htypechk.pas index 0fadb8cc1a..8f0689ecfa 100644 --- a/compiler/htypechk.pas +++ b/compiler/htypechk.pas @@ -773,8 +773,11 @@ implementation vecn: begin set_varstate(tbinarynode(p).right,vs_read,[vsf_must_be_valid]); - if not(tunarynode(p).left.resulttype.def.deftype in [stringdef,arraydef]) then - include(varstateflags,vsf_must_be_valid); + if (newstate in [vs_read,vs_readwritten]) or + not(tunarynode(p).left.resulttype.def.deftype in [stringdef,arraydef]) then + include(varstateflags,vsf_must_be_valid) + else if (newstate = vs_written) then + exclude(varstateflags,vsf_must_be_valid); p:=tunarynode(p).left; end; { do not parse calln } diff --git a/compiler/nld.pas b/compiler/nld.pas index bd8f9dc6ae..98e0777886 100644 --- a/compiler/nld.pas +++ b/compiler/nld.pas @@ -564,8 +564,8 @@ implementation end; resulttypepass(right); - set_varstate(left,vs_written,[]); set_varstate(right,vs_read,[vsf_must_be_valid]); + set_varstate(left,vs_written,[]); if codegenerror then exit; diff --git a/compiler/nmem.pas b/compiler/nmem.pas index 37ca6d6473..6ca4119648 100644 --- a/compiler/nmem.pas +++ b/compiler/nmem.pas @@ -443,9 +443,12 @@ implementation { this is like the function addr } inc(parsing_para_level); - { this is actually only "read", but treat it nevertheless as modified } - { due to the possible use of pointers } - set_varstate(left,vs_readwritten,[]); + { This is actually only "read", but treat it nevertheless as } + { modified due to the possible use of pointers } + { To avoid false positives regarding "uninitialised" } + { warnings when using arrays, perform it in two steps } + set_varstate(left,vs_written,[]); + set_varstate(left,vs_read,[]); dec(parsing_para_level); end; @@ -660,11 +663,16 @@ implementation ansi/widestring needs to be valid } valid:=is_dynamic_array(left.resulttype.def) or is_ansistring(left.resulttype.def) or - is_widestring(left.resulttype.def); + is_widestring(left.resulttype.def) or + { implicit pointer dereference -> pointer is read } + (left.resulttype.def.deftype = pointerdef); if valid then - set_varstate(left,vs_read,[vsf_must_be_valid]) - else - set_varstate(left,vs_read,[]); + set_varstate(left,vs_read,[vsf_must_be_valid]); +{ + A vecn is, just like a loadn, always part of an expression with its + own read/write and must_be_valid semantics. Therefore we don't have + to do anything else here, just like for loadn's +} set_varstate(right,vs_read,[vsf_must_be_valid]); if codegenerror then exit;