* don't evaluate sizeof(<type param>) as a constant to avoid arithmetic errors in constant folding, resolves #20192

git-svn-id: trunk@19285 -
This commit is contained in:
florian 2011-09-29 21:17:44 +00:00
parent 6f185f2184
commit 9d31a0e2f8
3 changed files with 53 additions and 2 deletions

1
.gitattributes vendored
View File

@ -11869,6 +11869,7 @@ tests/webtbs/tw2004.pp svneol=native#text/plain
tests/webtbs/tw20093.pp svneol=native#text/pascal
tests/webtbs/tw20093a.pp svneol=native#text/pascal
tests/webtbs/tw20119.pp -text svneol=native#test/pascal
tests/webtbs/tw20192.pp svneol=native#text/pascal
tests/webtbs/tw20257.pp svneol=native#text/plain
tests/webtbs/tw2028.pp svneol=native#text/plain
tests/webtbs/tw2030.pp svneol=native#text/plain

View File

@ -388,14 +388,17 @@ implementation
in_args:=true;
p1:=comp_expr(true,false);
consume(_RKLAMMER);
if (p1.nodetype<>typen) and
if ((p1.nodetype<>typen) and
(
(is_object(p1.resultdef) and
(oo_has_constructor in tobjectdef(p1.resultdef).objectoptions)) or
is_open_array(p1.resultdef) or
is_array_of_const(p1.resultdef) or
is_open_string(p1.resultdef)
) then
)) or
{ keep the function call if it is a type parameter to avoid arithmetic errors due to constant folding }
(p1.resultdef.typ=undefineddef) then
begin
statement_syssym:=geninlinenode(in_sizeof_x,false,p1);
{ no packed bit support for these things }

47
tests/webtbs/tw20192.pp Normal file
View File

@ -0,0 +1,47 @@
program SizeOfBug;
{$mode objfpc}{$H+}
type
generic TGen<_T> = class(TObject)
private
FField: _T;
public
constructor Create(Val: _T);
function Bug: Integer;
end;
{--- TGen.Create ---}
constructor TGen.Create(Val: _T);
begin
inherited Create;
FField := Val;
end;
{--- TGen.Bug ---}
function TGen.Bug : Integer;
begin
Result := 100000 div SizeOf(_T); // *** DIVISION BY ZERO ***
// THE FOLLOWING CODE IS OK !
//
// var
// S: Integer;
// begin
// S := SizeOf(_T);
// Result := 100000 div S;
end;
type
TGenInt = specialize TGen<Integer>;
var
V: TGenInt;
begin
V := V.Create(589);
WriteLn('V.Bug = ', V.Bug);
if V.Bug<>100000 div sizeof(pointer) then
halt(1);
V.Free;
writeln('ok');
end.