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;