[fpc-pascal] Range checks

2018-01-27 Thread C Western

The following innocuous looking code generates a range check error:

{$R+}
function Count: qword;
begin
  Result := 0;
end;
var
  i: Integer;
begin
  for i := 0 to Count-1 do
WriteLn(i);
end.

I can (more or less) see why, but it means that I can't (for example) 
compile the Cocoa widget set in 64 bit with bounds checking on, as then 
qword seems to be used as a count for, for example, NSarray.


Am I missing something?

Colin
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Range checks

2018-01-27 Thread Adriaan van Os

C Western wrote:

The following innocuous looking code generates a range check error:


The code shouldn't generate a range check error, as the target type is signed.

Note that Oberon was designed by Niklaus Wirth specifically to prevent this kind of problems. See 
the notes on type inclusion in section A.4.4 of An introduction to Oberon-2 



Apple has never heard of type inclusion or even range checking and is arbitrarily mixing signed and 
unsigned types.


Regards,

Adriaan van Os
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Range checks

2018-01-27 Thread Dmitry Boyarintsev
On Sat, Jan 27, 2018 at 10:06 AM, Adriaan van Os  wrote:
>
>
> The code shouldn't generate a range check error, as the target type is
> signed.
>

Count returns Unsigned Qword.
unsigned $ is beyond 32-bit boundary.

The similar issue, but more explicit.

{$R+}
function Count: qword;
begin
  Result := 0;
end;

var
  i: Integer;
  K : Qword;
begin
  K:=count-1;
  writeln(K);
  I:=k;  // <-- rangecheck error
  writeln(i);
end.

thanks,
Dmitry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Range checks

2018-01-27 Thread Sven Barth via fpc-pascal
On 27.01.2018 15:10, C Western wrote:
> The following innocuous looking code generates a range check error:
> 
> {$R+}
> function Count: qword;
> begin
>   Result := 0;
> end;
> var
>   i: Integer;
> begin
>   for i := 0 to Count-1 do
>     WriteLn(i);
> end.
> 
> I can (more or less) see why, but it means that I can't (for example)
> compile the Cocoa widget set in 64 bit with bounds checking on, as then
> qword seems to be used as a count for, for example, NSarray.
> 
> Am I missing something?

Integer is 32-bit, QWord is 64-bit. *Of course* there is a range check
error then. You need to use e.g. SizeInt as counter variable type in
those cases (SizeInt is 32-bit on 32-bit systems and 64-bit on 64-bit
systems).

Regards,
Sven

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Range checks

2018-01-27 Thread C Western

On 27/01/18 15:06, Adriaan van Os wrote:

C Western wrote:

The following innocuous looking code generates a range check error:


The code shouldn't generate a range check error, as the target type is 
signed.




Note that shifting the loop variable to Int64 still triggers the range 
check error. Using qword for the loop variable triggers an overflow error.


Apple has never heard of type inclusion or even range checking and is 
arbitrarily mixing signed and unsigned types.
I don't think this is an Apple issue - an unsigned type is not 
unreasonable for a count.



Colin
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Range checks

2018-01-27 Thread Dmitry Boyarintsev
On Sat, Jan 27, 2018 at 9:10 AM, C Western  wrote:

>
> I can (more or less) see why, but it means that I can't (for example)
> compile the Cocoa widget set in 64 bit with bounds checking on, as then
> qword seems to be used as a count for, for example, NSarray.
>
> how about taking objc approach:

 RangeCheckCount = objccategory(NSArray)
function intcount: Integer; message 'intcount';
  end;

{ RangeCheckCount }

function RangeCheckCount.intcount: Integer;
begin
  Result:=Integer(count);
end;

var
  arr : NSArray;

  for i:=0 to arr.intcount-1 do

?
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Range checks

2018-01-27 Thread Jonas Maebe

C Western wrote:
> The following innocuous looking code generates a range check error:
>
> {$R+}
> function Count: qword;
> begin
>   Result := 0;
> end;
> var
>   i: Integer;
> begin
>   for i := 0 to Count-1 do
> WriteLn(i);
> end.
>
> I can (more or less) see why

I changed the type used to evaluate for-loop bounds in ISO Pascal mode
because of https://bugs.freepascal.org/view.php?id=24318 . Maybe the
same should be done for other non-TP/Delphi modes too.


Jonas
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Range checks

2018-01-27 Thread Jonas Maebe

Jonas Maebe wrote:
> C Western wrote:
>> The following innocuous looking code generates a range check error:
>>
>> {$R+}
>> function Count: qword;
>> begin
>>   Result := 0;
>> end;
>> var
>>   i: Integer;
>> begin
>>   for i := 0 to Count-1 do
>> WriteLn(i);
>> end.
>>
>> I can (more or less) see why
> I changed the type used to evaluate for-loop bounds in ISO Pascal mode
> because of https://bugs.freepascal.org/view.php?id=24318 . Maybe the
> same should be done for other non-TP/Delphi modes too.

Actually, it won't help because "qword - 1" will still be evaluated as
qword. The issue is that there is no safe way to evaluate this with
range checking that is correct in all cases without a 128 bit integer type:
1) if you evaluate it as qword, you get a range error if count is 0 (as
above)
2) if you evaluate it as int64, then if count is high(int64)+1 you will
get a range error even though the result could be represented in int64

In this particular case, because the counter is 32 bit (which seems
quite unsafe for use with a container whose "count" property is 64 bit),
using int64 would be "correct", but it's not a systemic solution (as
shown above) and hence not something to implement in the language.


Jonas


Jonas
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Range checks

2018-01-27 Thread C Western

On 27/01/18 16:28, Jonas Maebe wrote:


Jonas Maebe wrote:

C Western wrote:

The following innocuous looking code generates a range check error:

{$R+}
function Count: qword;
begin
   Result := 0;
end;
var
   i: Integer;
begin
   for i := 0 to Count-1 do
 WriteLn(i);
end.

I can (more or less) see why

I changed the type used to evaluate for-loop bounds in ISO Pascal mode
because of https://bugs.freepascal.org/view.php?id=24318 . Maybe the
same should be done for other non-TP/Delphi modes too.


Actually, it won't help because "qword - 1" will still be evaluated as
qword. The issue is that there is no safe way to evaluate this with
range checking that is correct in all cases without a 128 bit integer type:
1) if you evaluate it as qword, you get a range error if count is 0 (as
above)
2) if you evaluate it as int64, then if count is high(int64)+1 you will
get a range error even though the result could be represented in int64

In this particular case, because the counter is 32 bit (which seems
quite unsafe for use with a container whose "count" property is 64 bit),
using int64 would be "correct", but it's not a systemic solution (as
shown above) and hence not something to implement in the language.



The actual code that triggered my interest was:

procedure LCLViewExtension.lclSetEnabled(AEnabled: Boolean);
var
  ns : NSArray;
  i  : integer;
  obj : NSObject;
begin
  ns := subviews;
  for i := 0 to ns.count - 1 do
  begin
obj := NSObject(ns.objectAtIndex( i ));
... process obj ...
  end;
end; 



I suppose i should be declared as the same type as ns.count which is 
NSUInteger = qword, but this will still trigger the error. You can avoid 
the problem by coding the loop as:


  for i := 1 to ns.count do
  begin
obj := NSObject(ns.objectAtIndex( i-1 ));

so I suppose the real flaw is that the first item is at index 0, rather 
than 1, but I don't think that is a battle I am going to win.


Given how common the above bit of code is likely to be, I can't see any 
way of fixing this without some work in the compiler.


Colin


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Range checks

2018-01-27 Thread Dmitry Boyarintsev
On Sat, Jan 27, 2018 at 12:30 PM, C Western  wrote:
>
> The actual code that triggered my interest was:
>
> procedure LCLViewExtension.lclSetEnabled(AEnabled: Boolean);
> var
>   ns : NSArray;
>   i  : integer;
>   obj : NSObject;
> begin
>   ns := subviews;
>   for i := 0 to ns.count - 1 do
>   begin
> obj := NSObject(ns.objectAtIndex( i ));
> ... process obj ...
>   end;
> end;
>
>
> Given how common the above bit of code is likely to be, I can't see any
> way of fixing this without some work in the compiler.


imho, bad approach to adjust compiler for not safe code.
However, getting a compiler warning would be nice.

Some time ago, the compiler has been extended with for-in syntax:

var
  SubView : NSView;
begin
  for SubView in ns.subviews do
  begin
.. process obj ...
  end

thanks,
Dmitry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Range checks

2018-01-27 Thread Dmitry Boyarintsev
On Sat, Jan 27, 2018 at 12:51 PM, Dmitry Boyarintsev <
skalogryz.li...@gmail.com> wrote:

>
> imho, bad approach to adjust compiler for not safe code.
> However, getting a compiler warning would be nice.
>
> Some time ago, the compiler has been extended with for-in syntax:
>
> var
>   SubView : NSView;
> begin
>   for SubView in ns.subviews do
>

That requires objectivec2 though
https://www.freepascal.org/docs-html/ref/refse76.html#x138-1611.10
(min version is macOS 10.5)

thanks,
Dmitry
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal