Formal arguments passed by reference in fork-join_none

In reply to puranik.sunil@tcs.com:
I believe what you are asking is this:

module top;
   function automatic foo;
      bit local_prm;
      fork
	 begin : forked
	    tsk1(local_prm);
	    $display("local_prm %b exists till this process ends %t",local_prm, $time);
	 end
      join_none
   endfunction
   task automatic tsk1(output bit prm_out); // ref bit prm_out also allowed
      #10 prm_out = 1;
   endtask

   initial foo();
endmodule

This is allowed because:

The lifetime of a fork-join block (see 9.3.2) shall encompass the execution of all processes spawned by the
block. The lifetime of a scope enclosing any fork-join block includes the lifetime of the fork-join block.

Solocal_prm remains active while the process forked is active even after foo() returns. And it doesn’t matter if prm_out gets passed by reference or not. So it’s a little more complex than just a call stack determining the lifetime of an automatic.

But let’s go back to your original post and modify this example

module top;
   function automatic foo;
      bit prm;
      fork
	 begin : forked
	    tsk1(prm);
	    $display("prm %b exists till this process ends %t",prm, $time);
	 end
      join_none
   endfunction
   task automatic tsk1(ref bit prm_out);
      #10 prm_out = 1;
      fork
	 tsk2(prm_out);
      join_none
   endtask
   task automatic tsk2(ref bit prm_out); // this is illegal
      #10 prm_out = 0;
   endtask
   initial foo;
endmodule

For this to work, the compiler would need to know the lifetime of prm goes beyond the lifetime of the forked process. Generally, it’s not a good idea to have to look inside the task you are calling in determining the behavior of code outside the task call.