1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
import org.checkerframework.checker.initialization.qual.*;
import org.checkerframework.checker.nullness.qual.*;
// This test does not correctly work in the FBC system,
// see https://github.com/typetools/checker-framework/issues/223
class RawField {
public @UnknownInitialization RawField a;
public RawField() {
// :: error: (assignment.type.incompatible)
a = null;
this.a = this;
a = this;
}
// :: error: (initialization.fields.uninitialized)
public RawField(boolean foo) {}
void t1() {
// :: error: (method.invocation.invalid)
a.t1();
}
void t2(@UnknownInitialization RawField a) {
this.a = a;
}
}
class Options {
@UnknownInitialization Object arg;
public Options(@UnknownInitialization Object arg) {
this.arg = arg;
}
public void parse_or_usage() {
// use arg only under the assumption that it is @UnknownInitialization
}
}
class MultiVersionControl {
@SuppressWarnings("fbc") // see https://github.com/typetools/checker-framework/issues/223
public void parseArgs(@UnknownInitialization MultiVersionControl this) {
Options options = new Options(this);
options.parse_or_usage();
}
}
// TODO: This checks that forbidden field assignments do not occur. (The
// FBC type system permits arbitrary assignments in a constructor, but it
// also makes assumptions that our implementation does not currently check.)
// class HasStaticUnknownInitializationField {
// static @UnknownInitialization Object f;
// }
//
// class UseUnknownInitializationField {
//
// Object f;
//
// public UseUnknownInitializationField() {
// // :: (initialization.invalid.field.write.in.constructor)
// f = HasStaticUnknownInitializationField.f;
// }
//
// }
|