mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-08 18:26:24 +02:00
* fixed webtbf/tw3631
* properly set vs_read/written status for tp-style objects without vmt of which a method is called git-svn-id: trunk@6005 -
This commit is contained in:
parent
125ed611b0
commit
9ad579855e
@ -765,22 +765,29 @@ implementation
|
|||||||
const
|
const
|
||||||
vstrans: array[tvarstate,tvarstate] of tvarstate = (
|
vstrans: array[tvarstate,tvarstate] of tvarstate = (
|
||||||
{ vs_none -> ... }
|
{ vs_none -> ... }
|
||||||
(vs_none,vs_declared,vs_initialised,vs_read,vs_read_not_warned,vs_written,vs_readwritten),
|
(vs_none,vs_declared,vs_initialised,vs_read,vs_read_not_warned,vs_referred_not_inited,vs_written,vs_readwritten),
|
||||||
{ vs_declared -> ... }
|
{ vs_declared -> ... }
|
||||||
(vs_none,vs_declared,vs_initialised,vs_read,vs_read_not_warned,vs_written,vs_readwritten),
|
(vs_none,vs_declared,vs_initialised,vs_read,vs_read_not_warned,vs_referred_not_inited,vs_written,vs_readwritten),
|
||||||
{ vs_initialised -> ... }
|
{ vs_initialised -> ... }
|
||||||
(vs_none,vs_initialised,vs_initialised,vs_read,vs_read,vs_written,vs_readwritten),
|
(vs_none,vs_initialised,vs_initialised,vs_read,vs_read,vs_read,vs_written,vs_readwritten),
|
||||||
{ vs_read -> ... }
|
{ vs_read -> ... }
|
||||||
(vs_none,vs_read,vs_read,vs_read,vs_read_not_warned,vs_readwritten,vs_readwritten),
|
(vs_none,vs_read,vs_read,vs_read,vs_read,vs_read,vs_readwritten,vs_readwritten),
|
||||||
{ vs_read_not_warned -> ... }
|
{ vs_read_not_warned -> ... }
|
||||||
(vs_none,vs_read_not_warned,vs_read,vs_read,vs_read_not_warned,vs_readwritten,vs_readwritten),
|
(vs_none,vs_read_not_warned,vs_read,vs_read,vs_read_not_warned,vs_read_not_warned,vs_readwritten,vs_readwritten),
|
||||||
|
{ vs_referred_not_inited }
|
||||||
|
(vs_none,vs_referred_not_inited,vs_read,vs_read,vs_read,vs_referred_not_inited,vs_readwritten,vs_readwritten),
|
||||||
{ vs_written -> ... }
|
{ vs_written -> ... }
|
||||||
(vs_none,vs_written,vs_written,vs_readwritten,vs_readwritten,vs_written,vs_readwritten),
|
(vs_none,vs_written,vs_written,vs_readwritten,vs_readwritten,vs_written,vs_written,vs_readwritten),
|
||||||
{ vs_readwritten -> ... }
|
{ vs_readwritten -> ... }
|
||||||
(vs_none,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten));
|
(vs_none,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten));
|
||||||
var
|
var
|
||||||
hsym : tabstractvarsym;
|
hsym : tabstractvarsym;
|
||||||
begin
|
begin
|
||||||
|
{ make sure we can still warn about uninitialised use after high(v), @v etc }
|
||||||
|
if (newstate = vs_read) and
|
||||||
|
not(vsf_must_be_valid in varstateflags) then
|
||||||
|
newstate := vs_referred_not_inited;
|
||||||
|
|
||||||
while assigned(p) do
|
while assigned(p) do
|
||||||
begin
|
begin
|
||||||
case p.nodetype of
|
case p.nodetype of
|
||||||
@ -822,7 +829,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
hsym:=tabstractvarsym(tloadnode(p).symtableentry);
|
hsym:=tabstractvarsym(tloadnode(p).symtableentry);
|
||||||
if (vsf_must_be_valid in varstateflags) and
|
if (vsf_must_be_valid in varstateflags) and
|
||||||
(hsym.varstate in [vs_declared,vs_read_not_warned]) then
|
(hsym.varstate in [vs_declared,vs_read_not_warned,vs_referred_not_inited]) then
|
||||||
begin
|
begin
|
||||||
{ Give warning/note for uninitialized locals }
|
{ Give warning/note for uninitialized locals }
|
||||||
if assigned(hsym.owner) and
|
if assigned(hsym.owner) and
|
||||||
|
@ -2144,15 +2144,15 @@ implementation
|
|||||||
Also allow it for simple loads }
|
Also allow it for simple loads }
|
||||||
if (procdefinition.proctypeoption=potype_constructor) or
|
if (procdefinition.proctypeoption=potype_constructor) or
|
||||||
((hpt.nodetype=loadn) and
|
((hpt.nodetype=loadn) and
|
||||||
(
|
(methodpointer.resultdef.typ=objectdef) and
|
||||||
(methodpointer.resultdef.typ=classrefdef) or
|
not(oo_has_virtual in tobjectdef(methodpointer.resultdef).objectoptions)
|
||||||
(
|
|
||||||
(methodpointer.resultdef.typ=objectdef) and
|
|
||||||
not(oo_has_virtual in tobjectdef(methodpointer.resultdef).objectoptions)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) then
|
) then
|
||||||
set_varstate(methodpointer,vs_read,[])
|
{ a constructor will and a method may write something to }
|
||||||
|
{ the fields }
|
||||||
|
set_varstate(methodpointer,vs_written,[])
|
||||||
|
else if ((hpt.nodetype=loadn) and
|
||||||
|
(methodpointer.resultdef.typ=classrefdef)) then
|
||||||
|
set_varstate(methodpointer,vs_read,[])
|
||||||
else
|
else
|
||||||
set_varstate(methodpointer,vs_read,[vsf_must_be_valid]);
|
set_varstate(methodpointer,vs_read,[vsf_must_be_valid]);
|
||||||
|
|
||||||
|
@ -452,7 +452,9 @@ implementation
|
|||||||
{ To avoid false positives regarding "uninitialised" }
|
{ To avoid false positives regarding "uninitialised" }
|
||||||
{ warnings when using arrays, perform it in two steps }
|
{ warnings when using arrays, perform it in two steps }
|
||||||
set_varstate(left,vs_written,[]);
|
set_varstate(left,vs_written,[]);
|
||||||
set_varstate(left,vs_read,[]);
|
{ vsf_must_be_valid so it doesn't get changed into }
|
||||||
|
{ vsf_referred_not_inited }
|
||||||
|
set_varstate(left,vs_read,[vsf_must_be_valid]);
|
||||||
dec(parsing_para_level);
|
dec(parsing_para_level);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -393,9 +393,27 @@ type
|
|||||||
macrosym
|
macrosym
|
||||||
);
|
);
|
||||||
|
|
||||||
{ State of the variable, if it's declared, assigned or used }
|
{ State of the variable:
|
||||||
|
vs_declared: variable has been declared, not initialised
|
||||||
|
(e.g. normal variable, out parameter)
|
||||||
|
vs_initialised: variable has been declared and is valid
|
||||||
|
(e.g. typed constant, var/const parameter)
|
||||||
|
vs_read: variable has been read and the read was checked for validity
|
||||||
|
(so a warning has been given if necessary)
|
||||||
|
vs_read_not_warned: variable has been read, but we didn't warn about
|
||||||
|
whether or not the variable was valid
|
||||||
|
(e.g. read of global variable -> warn at end of compilation unit if
|
||||||
|
the state is vs_read_not_warned, since that means it's only read and
|
||||||
|
never written)
|
||||||
|
vs_referred_not_inited: variable has been used in length/low/high/@/...
|
||||||
|
expression, was not yet initialised and needn't be at that time
|
||||||
|
(e.g. length() of a statically allocated array, or sizeof(variable))
|
||||||
|
vs_written: variable has been assigned/written to, but not yet read
|
||||||
|
(e.g. assigning something to a variable/parameter)
|
||||||
|
vs_readwritten: variable has been written to and read from }
|
||||||
tvarstate=(vs_none,
|
tvarstate=(vs_none,
|
||||||
vs_declared,vs_initialised,vs_read,vs_read_not_warned,vs_written,vs_readwritten
|
vs_declared,vs_initialised,vs_read,vs_read_not_warned,
|
||||||
|
vs_referred_not_inited,vs_written,vs_readwritten
|
||||||
);
|
);
|
||||||
|
|
||||||
tvarspez = (vs_value,vs_const,vs_var,vs_out);
|
tvarspez = (vs_value,vs_const,vs_var,vs_out);
|
||||||
|
Loading…
Reference in New Issue
Block a user