o patch by Michael Denisenko, resolves #14734:

* fixes memory leaks in case of string code
  * replace usage of strcmp
  * improved tests

git-svn-id: trunk@13830 -
This commit is contained in:
florian 2009-10-09 20:40:22 +00:00
parent 93171fdc23
commit 44aed2af60
28 changed files with 135 additions and 90 deletions

View File

@ -192,6 +192,7 @@ interface
{ some helper routines } { some helper routines }
function get_ordinal_value(p : tnode) : TConstExprInt; function get_ordinal_value(p : tnode) : TConstExprInt;
function get_string_value(p : tnode; is_wide : boolean = false) : TConstString; function get_string_value(p : tnode; is_wide : boolean = false) : TConstString;
function compare_strings(str1, str2: pchar) : longint;
function is_constresourcestringnode(p : tnode) : boolean; function is_constresourcestringnode(p : tnode) : boolean;
function is_emptyset(p : tnode):boolean; function is_emptyset(p : tnode):boolean;
function genconstsymtree(p : tconstsym) : tnode; function genconstsymtree(p : tconstsym) : tnode;
@ -254,11 +255,12 @@ implementation
if (not is_wide) then if (not is_wide) then
begin begin
if ordValRecord.signed then if ordValRecord.signed then
stringVal := char(ordValRecord.svalue) + ''#0 stringVal := char(ordValRecord.svalue)
else else
stringVal := char(ordValRecord.uvalue) + ''#0; stringVal := char(ordValRecord.uvalue);
getmem(pCharVal, length(stringVal)); getmem(pCharVal, length(stringVal) + 1);
strpcopy(pCharVal, stringVal); strpcopy(pCharVal, stringVal);
pCharVal[length(stringVal)] := #0;
get_string_value := pCharVal; get_string_value := pCharVal;
end end
else else
@ -317,6 +319,25 @@ implementation
end; end;
end; end;
function compare_strings(str1, str2: pchar) : longint;
var
minlen, len1, len2: integer;
begin
len1 := length(str1);
len2 := length(str2);
if len1 < len2 then
minlen := len1
else
minlen := len2;
minlen := comparebyte(str1^, str2^, minlen);
if minlen = 0 then
minlen := len1 - len2;
Result := minlen;
end;
function is_constresourcestringnode(p : tnode) : boolean; function is_constresourcestringnode(p : tnode) : boolean;
begin begin
is_constresourcestringnode:=(p.nodetype=loadn) and is_constresourcestringnode:=(p.nodetype=loadn) and

View File

@ -766,7 +766,7 @@ implementation
condit := caddnode.create( condit := caddnode.create(
equaln, left.getcopy, cstringconstnode.createstr(labtree^._low_str)); equaln, left.getcopy, cstringconstnode.createstr(labtree^._low_str));
if (strcomp(labtree^._low_str, labtree^._high_str) <> 0) then if (compare_strings(labtree^._low_str, labtree^._high_str) <> 0) then
begin begin
condit.nodetype := gten; condit.nodetype := gten;
condit := caddnode.create( condit := caddnode.create(
@ -791,10 +791,17 @@ implementation
init_block:=nil; init_block:=nil;
expectloc:=LOC_VOID; expectloc:=LOC_VOID;
{ evalutes the case expression }
firstpass(left);
set_varstate(left,vs_read,[vsf_must_be_valid]);
if codegenerror then
exit;
{ Load caseexpr into temp var if complex. } { Load caseexpr into temp var if complex. }
{ No need to do this for ordinal, because } { No need to do this for ordinal, because }
{ in that case caseexpr is generated once } { in that case caseexpr is generated once }
if (labels^.label_type = ltConstString) and (not valid_for_addr(left, false)) then if (labels^.label_type = ltConstString) and (not valid_for_addr(left, false)) and
(blocks.count > 0) then
begin begin
init_block := internalstatements(stmt); init_block := internalstatements(stmt);
tempcaseexpr := tempcaseexpr :=
@ -811,12 +818,6 @@ implementation
typecheckpass(left); typecheckpass(left);
end; end;
{ evalutes the case expression }
firstpass(left);
set_varstate(left,vs_read,[vsf_must_be_valid]);
if codegenerror then
exit;
{ first case } { first case }
for i:=0 to blocks.count-1 do for i:=0 to blocks.count-1 do
firstpass(pcaseblock(blocks[i])^.statement); firstpass(pcaseblock(blocks[i])^.statement);
@ -1065,7 +1066,7 @@ implementation
if (str_type in [cst_widestring, cst_unicodestring]) then if (str_type in [cst_widestring, cst_unicodestring]) then
result := comparewidestrings(pcompilerwidestring(l), pcompilerwidestring(h)) result := comparewidestrings(pcompilerwidestring(l), pcompilerwidestring(h))
else else
result := strcomp(l, h); result := compare_strings(l, h);
end; end;
var var

View File

@ -183,8 +183,8 @@ implementation
end; end;
hl1:=0; hl1:=0;
hl2:=0; hl2:=0;
sl1:=''; sl1:=nil;
sl2:=''; sl2:=nil;
if (p.nodetype=rangen) then if (p.nodetype=rangen) then
begin begin
{ type check for string case statements } { type check for string case statements }
@ -197,7 +197,7 @@ implementation
if ( if (
(is_wide_or_unicode_string(casedef) and ( (is_wide_or_unicode_string(casedef) and (
comparewidestrings(pcompilerwidestring(sl1), pcompilerwidestring(sl2)) > 0)) or comparewidestrings(pcompilerwidestring(sl1), pcompilerwidestring(sl2)) > 0)) or
((not is_wide_or_unicode_string(casedef)) and (strcomp(sl1, sl2) > 0))) then ((not is_wide_or_unicode_string(casedef)) and (compare_strings(sl1, sl2) > 0))) then
CGMessage(parser_e_case_lower_less_than_upper_bound); CGMessage(parser_e_case_lower_less_than_upper_bound);
end end
{ type checking for ordinal case statements } { type checking for ordinal case statements }
@ -245,6 +245,29 @@ implementation
end; end;
end; end;
p.free; p.free;
if caseofstring then
begin
if is_wide_or_unicode_string(casedef) then
begin
if assigned(sl1) then
donewidestring(pcompilerwidestring(sl1));
if assigned(sl2) then
donewidestring(pcompilerwidestring(sl2));
end
else
begin
if assigned(sl1) then
begin
freemem(sl1);
sl1 := nil;
end;
if assigned(sl2) then
begin
freemem(sl2);
sl2 := nil;
end;
end;
end;
if token=_COMMA then if token=_COMMA then
consume(_COMMA) consume(_COMMA)
else else

View File

@ -3,9 +3,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H+} {$H+}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -3,9 +3,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -5,9 +5,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin

View File

@ -4,9 +4,9 @@
{$H-} {$H-}
var var
my_str: string; my_str: string;
my_str_wide: string; my_str_wide: widestring;
my_str_ansi: string; my_str_ansi: ansistring;
my_str_uni: string; my_str_uni: unicodestring;
i: integer; i: integer;
begin begin