mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-18 18:31:41 +02:00
* 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:
parent
6f185f2184
commit
9d31a0e2f8
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -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
|
||||
|
@ -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
47
tests/webtbs/tw20192.pp
Normal 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.
|
Loading…
Reference in New Issue
Block a user