* never use a linear table for enum<->string translation when two enums have

the same value (mantis #22570)

git-svn-id: trunk@22276 -
This commit is contained in:
Jonas Maebe 2012-08-31 18:51:59 +00:00
parent a6e18e0f68
commit 4cae00f97a
3 changed files with 83 additions and 1 deletions

1
.gitattributes vendored
View File

@ -12805,6 +12805,7 @@ tests/webtbs/tw22490.pp svneol=native#text/plain
tests/webtbs/tw2250.pp svneol=native#text/plain tests/webtbs/tw2250.pp svneol=native#text/plain
tests/webtbs/tw22502.pp svneol=native#text/plain tests/webtbs/tw22502.pp svneol=native#text/plain
tests/webtbs/tw22561.pp svneol=native#text/plain tests/webtbs/tw22561.pp svneol=native#text/plain
tests/webtbs/tw22570.pp svneol=native#text/plain
tests/webtbs/tw2259.pp svneol=native#text/plain tests/webtbs/tw2259.pp svneol=native#text/plain
tests/webtbs/tw22593.pp svneol=native#text/plain tests/webtbs/tw22593.pp svneol=native#text/plain
tests/webtbs/tw2260.pp svneol=native#text/plain tests/webtbs/tw2260.pp svneol=native#text/plain

View File

@ -973,7 +973,7 @@ implementation
procedure enumdef_rtti_ord2stringindex(const sym_count:longint; const offsets:plongint; const syms:Penumsym; const st:longint); procedure enumdef_rtti_ord2stringindex(const sym_count:longint; const offsets:plongint; const syms:Penumsym; const st:longint);
var rttilab:Tasmsymbol; var rttilab:Tasmsymbol;
h,i,o:longint; h,i,o,prev_value:longint;
mode:(lookup,search); {Modify with care, ordinal value of enum is written.} mode:(lookup,search); {Modify with care, ordinal value of enum is written.}
r:single; {Must be real type because of integer overflow risk.} r:single; {Must be real type because of integer overflow risk.}
@ -986,10 +986,24 @@ implementation
i:=1; i:=1;
r:=0; r:=0;
h:=syms[0].value; {Next expected enum value is min.} h:=syms[0].value; {Next expected enum value is min.}
{ set prev_value for the first iteration to a value that is
different from the first one without risking overflow (it's used
to detect whether two enum values are the same) }
if h=0 then
prev_value:=1
else
prev_value:=0;
while i<sym_count do while i<sym_count do
begin begin
{ if two enum values are the same, we have to create a table }
if (prev_value=h) then
begin
mode:=search;
break;
end;
{Calculate size of hole between values. Avoid integer overflows.} {Calculate size of hole between values. Avoid integer overflows.}
r:=r+(single(syms[i].value)-single(h))-1; r:=r+(single(syms[i].value)-single(h))-1;
prev_value:=h;
h:=syms[i].value; h:=syms[i].value;
inc(i); inc(i);
end; end;

67
tests/webtbs/tw22570.pp Normal file
View File

@ -0,0 +1,67 @@
type
TChomskyType = ( ctNoneGrammar = 0,
ctType0 = 1, ctRecursivelyEnumerable = ctType0,
ctType1 = 2, ctContextSensitive = ctType1,
ctType2 = 3, ctContextFree = ctType2,
ctType3 = 4, ctRegular = ctType3);
var
e: TChomskyType;
err: longint;
s: shortstring;
begin
val('ctType0',e,err);
if e<>ctType0 then
halt(1);
val('ctRecursivelyEnumerable',e,err);
if e<>ctRecursivelyEnumerable then
halt(2);
val('ctType1',e,err);
if e<>ctType1 then
halt(3);
val('ctContextSensitive',e,err);
if e<>ctContextSensitive then
halt(4);
val('ctType2',e,err);
if e<>ctType2 then
halt(5);
val('ctContextFree',e,err);
if e<>ctContextFree then
halt(6);
str(ctType0,s);
{ could be either since they have the same value }
if (s<>'ctType0') and
(s<>'ctRecursivelyEnumerable') then
halt(7);
str(ctRecursivelyEnumerable,s);
if (s<>'ctType0') and
(s<>'ctRecursivelyEnumerable') then
halt(8);
str(ctType1,s);
if (s<>'ctType1') and
(s<>'ctContextSensitive') then
halt(9);
str(ctContextSensitive,s);
if (s<>'ctType1') and
(s<>'ctContextSensitive') then
halt(9);
str(ctType2,s);
if (s<>'ctType2') and
(s<>'ctContextFree') then
halt(10);
str(ctContextFree,s);
if (s<>'ctType2') and
(s<>'ctContextFree') then
halt(10);
end.