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 = x.release(); // 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.