New Issue: Early return from an initializer leaves fields uninitialized

18524, "ronawho", "Early return from an initializer leaves fields uninitialized ", "2021-10-06T15:26:30Z"

Having an early return in an initializer leaves the fields uninitialized and does not produce a warning or error to indicate that.

In the following example the early return leave the fields uninitialized and so their default values are just random stack memory:

use CPtr;
record lowLevelLocalizingSlice {
    type t;
    var ptr: c_ptr(t) = c_nil;
    var isOwned: bool = false;
    var initSentinel = 314;

    proc init(A: [] ?t, region: range(?)) {
      this.t = t;
      if region.isEmpty() {
        return;
      }

      this.ptr = c_malloc(t, region.size);
      this.isOwned = true;
      for i in 0..<region.size {
        this.ptr[i] = A[region.low + i];
      }
    }

    proc deinit() {
      if isOwned then c_free(ptr);
    }
}

var A: [1..10] int;
writeln(new lowLevelLocalizingSlice(A, 1..1));
writeln(new lowLevelLocalizingSlice(A, 1..0));
(ptr = 0x7f8492604280, isOwned = true, initSentinel = 314)
(ptr = nil, isOwned = false, initSentinel = 1) // initSentinel should be 314

In this small test case, it's easy to change to if !region.isEmpty() { //realInit } or something, but the original code is from arkouda/AryUtil.chpl at be1408767b8933513baf9090a478541b1fe52abc · Bears-R-Us/arkouda · GitHub where I find the early return makes the code easier to read compared to having extra branches and indentation in the "real" init code.

In an Arkouda test, the random stack memory we got caused isOwned to be true and so we tried to free a random address, which is what caused us to notice this issue.

I don't have a strong preference for inserting default field init before the return or just making this a user error, but something to prevent error would be nice.