import org.checkerframework.checker.lock.qual.*;
// Initializers and constructors are synchronized over 'this'
// but not over their class's fields
public @GuardedBy({}) class Constructors {
static class MyClass {
public Object field;
}
final MyClass unlocked = new MyClass();
@GuardedBy("this") MyClass guardedThis = new MyClass();
@GuardedBy("unlocked") MyClass guardedOther = new MyClass();
static final MyClass unlockedStatic = new MyClass();
@GuardedBy("unlockedStatic") MyClass nonstaticGuardedByStatic = new MyClass();
//:: error: (expression.unparsable.type.invalid)
static @GuardedBy("unlocked") MyClass staticGuardedByNonStatic = new MyClass();
static @GuardedBy("unlockedStatic") MyClass staticGuardedByStatic = new MyClass();
Object initializedObject1 = unlocked.field;
Object initializedObject2 = guardedThis.field;
//:: error: (lock.not.held)
Object initializedObject3 = guardedOther.field;
//:: error: (expression.unparsable.type.invalid)
Object initializedObject4 = staticGuardedByNonStatic.field;
//:: error: (lock.not.held)
Object initializedObject5 = nonstaticGuardedByStatic.field;
//:: error: (lock.not.held)
Object initializedObject6 = staticGuardedByStatic.field;
Constructors() {
unlocked.field.toString();
guardedThis.field.toString();
//:: error: (lock.not.held)
guardedOther.field.toString();
//:: error: (expression.unparsable.type.invalid)
staticGuardedByNonStatic.field.toString();
//:: error: (lock.not.held)
nonstaticGuardedByStatic.field.toString();
//:: error: (lock.not.held)
staticGuardedByStatic.field.toString();
}
}