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:
// ex.chpl
class MyClass {
var x: int;
proc method() { }
}
var obj: 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:
ex.chpl:9: error: attempt to dereference nil
ex.chpl:9: note: variable obj is nil at this point
ex.chpl:8: note: this statement may be relevant
ex.chpl:13: error: attempt to dereference nil
ex.chpl:12: note: this statement may be relevant
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
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.