Re: [fpc-devel] Capturing addresses

2019-11-11 Thread Marc Weustink via fpc-devel

Jonas Maebe wrote:

Hi,

Does anyone know what the accepted/excepted behaviour is regarding the
capture of addresses of var/out/const-by-address/constref parameters?

For example:

var
   g: longint;
   p: plongint;

procedure test(var l: longint);
begin
   p:=@l;
end;

begin
   test(g);
end.

After test() executes, p now contains the address of g (the '@' operator
does not return the address of g's address on the stack; it returns the
actual address of g). This means that g's address has been captured by
test(). This can obviously lead to wrong/dangerous situations, e.g. if g
was not a global variable, but a local variable of another procedure.
That said, it is a legal expression.

I would like to teach the compiler to be able to assume that addresses
of variables are not captured merely because they are passed by
reference. There will also be a switch to toggle this assumption,
because fortunately it the behaviour is completely defined by the callee
side (so if you know that a unit does this, compiling that unit
appropriately is sufficient to ensure it will always work correctly).

The question is: should the compiler by default assume that such
addresses are not captured, or that they are captured? Does anyone know
if a lot of code exists that does this?


I've a lot of (interfacing) code where the address of a var is used, 
where the resulting pointer used locally. I don't think I've code which 
stores that pointer somewhere outside the procedure.


Marc
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Capturing addresses

2019-11-10 Thread Marco Borsari via fpc-devel

Il 10/11/2019 14:36, Jonas Maebe ha scritto:

Hi,

Does anyone know what the accepted/excepted behaviour is regarding the
capture of addresses of var/out/const-by-address/constref parameters?

For example:

var
   g: longint;
   p: plongint;

procedure test(var l: longint);
begin
   p:=@l;
end;

begin
   test(g);
end.

The question is: should the compiler by default assume that such
addresses are not captured, or that they are captured? Does anyone know
if a lot of code exists that does this?


To me p:=@l should be simply refused by the compiler as it happens in 
case of p:=l.

Marco
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Capturing addresses

2019-11-10 Thread Martin Frb

On 10/11/2019 15:05, Jonas Maebe wrote:

On 10/11/2019 14:58, Martin Frb wrote:

So I am trying to understand what the difference (in terms of safety)
is? (except that the none "var param" is always unsafe, the "var param"
is only sometimes unsafe)?

If you are talking about the safety of accesses after the capturing
routine has exited, then that is indeed the only difference.

Ok then I am missing some (maybe internal?) detail. Not to important, 
just curiosity.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Capturing addresses

2019-11-10 Thread Jonas Maebe
On 10/11/2019 14:58, Martin Frb wrote:
> So I am trying to understand what the difference (in terms of safety)
> is? (except that the none "var param" is always unsafe, the "var param"
> is only sometimes unsafe)?

If you are talking about the safety of accesses after the capturing
routine has exited, then that is indeed the only difference.

> Also out of interest, what would change if you ...
>> teach the compiler to be able to assume that addresses
>> of variables are not captured merely because they are passed by
>> reference 

It should allow the compiler to get rid of a lot of temporary function
results (and copying those temporary results to their final
destination), in particular for shortstring and set operations, and for
overloaded operators that work with records.


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


Re: [fpc-devel] Capturing addresses

2019-11-10 Thread Martin Frb

On 10/11/2019 14:36, Jonas Maebe wrote:

For example:

var
   g: longint;
   p: plongint;

procedure test(var l: longint);
begin
   p:=@l;
end;

begin
   test(g);
end.

After test() executes, p now contains the address of g (the '@' operator
does not return the address of g's address on the stack; it returns the
actual address of g). This means that g's address has been captured by
test(). This can obviously lead to wrong/dangerous situations, e.g. if g
was not a global variable, but a local variable of another procedure.
That said, it is a legal expression.


Your example shows the safe case (p is and will continue to be safe).

In the unsafe case (g to be a local var), this is similar to none "var 
param"


var
  p: plongint;
procedure test(l: longint);
begin
  p:=@l;
end;

p will be a dangling pointer, after "test" exited.
The same as in your example, but with the case that "g" is local, p 
becomes dangling when "g" goes out of scope.


So I am trying to understand what the difference (in terms of safety) 
is? (except that the none "var param" is always unsafe, the "var param" 
is only sometimes unsafe)?


Also out of interest, what would change if you ...

teach the compiler to be able to assume that addresses
of variables are not captured merely because they are passed by
reference


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] Capturing addresses

2019-11-10 Thread Jonas Maebe
Hi,

Does anyone know what the accepted/excepted behaviour is regarding the
capture of addresses of var/out/const-by-address/constref parameters?

For example:

var
  g: longint;
  p: plongint;

procedure test(var l: longint);
begin
  p:=@l;
end;

begin
  test(g);
end.

After test() executes, p now contains the address of g (the '@' operator
does not return the address of g's address on the stack; it returns the
actual address of g). This means that g's address has been captured by
test(). This can obviously lead to wrong/dangerous situations, e.g. if g
was not a global variable, but a local variable of another procedure.
That said, it is a legal expression.

I would like to teach the compiler to be able to assume that addresses
of variables are not captured merely because they are passed by
reference. There will also be a switch to toggle this assumption,
because fortunately it the behaviour is completely defined by the callee
side (so if you know that a unit does this, compiling that unit
appropriately is sufficient to ensure it will always work correctly).

The question is: should the compiler by default assume that such
addresses are not captured, or that they are captured? Does anyone know
if a lot of code exists that does this?


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