Checking for Nil Dereferences

The Chapel compiler includes two different mechanisms to check for nil dereferences. First, at compile-time, the compiler looks for places where it can prove a nil will be dereferenced or a method called on nil. When it can find such a case, it raises an error.

The second mechanism is a run-time check inserted at each method call on an object. It checks that the receiver object is not nil. These checks are on by default and can be disabled by –fast, –no-checks, or –no-nil-checks.

Example of Compile-time Nil Checking

Consider this example program:

class MyClass {
  var x: int;
  proc method() {}
}

proc main() {
  var obj: owned MyClass?; // default initializes 'obj' to store 'nil'
  obj!.method();

  var x = new owned MyClass(1)?;
  var y = owned.release(x); // now 'x' stores 'nil'
  x!.method();
}

Compiling this program will produce the following compilation errors:

NilCheckingExamples.chpl:11: In function 'main':
NilCheckingExamples.chpl:13: error: applying postfix-! to nil
NilCheckingExamples.chpl:12: note: 'obj' is set to nil here
NilCheckingExamples.chpl:17: error: applying postfix-! to nil
NilCheckingExamples.chpl:16: note: 'x' is set to nil here

Limitations of Compile-time Nil Checking

The compiler analysis for nil checking only does per-function analysis using very conservative alias analysis rules. It cannot detect all cases where a nil is dereferenced. Here are some limitations of the analysis:

  • it gives up in certain complex control flow situations

  • it does not track may-alias sets

  • it is not interprocedural

Additionally, compile-time checks are not performed for module-scope code. If the code in the previous example were moved outside main, then the program would compile without issues.

Nonetheless we hope that the additional checking provided by this pass is useful. If you run into a surprising case where it reports an error, please file a bug report. Also, note that using the compiler flag --no-compile-time-nil-checking will disable these checks. However, the exact nature of the checking and the name of the flag are likely to change in future releases.