mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 18:47:52 +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
|
||||
vstrans: array[tvarstate,tvarstate] of tvarstate = (
|
||||
{ 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_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_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_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_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_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_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
|
||||
hsym : tabstractvarsym;
|
||||
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
|
||||
begin
|
||||
case p.nodetype of
|
||||
@ -822,7 +829,7 @@ implementation
|
||||
begin
|
||||
hsym:=tabstractvarsym(tloadnode(p).symtableentry);
|
||||
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
|
||||
{ Give warning/note for uninitialized locals }
|
||||
if assigned(hsym.owner) and
|
||||
|
@ -2144,15 +2144,15 @@ implementation
|
||||
Also allow it for simple loads }
|
||||
if (procdefinition.proctypeoption=potype_constructor) or
|
||||
((hpt.nodetype=loadn) and
|
||||
(
|
||||
(methodpointer.resultdef.typ=classrefdef) or
|
||||
(
|
||||
(methodpointer.resultdef.typ=objectdef) and
|
||||
not(oo_has_virtual in tobjectdef(methodpointer.resultdef).objectoptions)
|
||||
)
|
||||
)
|
||||
(methodpointer.resultdef.typ=objectdef) and
|
||||
not(oo_has_virtual in tobjectdef(methodpointer.resultdef).objectoptions)
|
||||
) 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
|
||||
set_varstate(methodpointer,vs_read,[vsf_must_be_valid]);
|
||||
|
||||
|
@ -452,7 +452,9 @@ implementation
|
||||
{ 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,[]);
|
||||
{ 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);
|
||||
end;
|
||||
|
||||
|
@ -393,9 +393,27 @@ type
|
||||
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,
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user