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;