/* * Copyright (c) 2017-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import com.facebook.infer.annotation.ThreadSafe; @ThreadSafe class DeepOwnership { DeepOwnership next; static DeepOwnership global; void globalNotOwnedBad() { global.next = null; } void reassignBaseToGlobalBad(){ DeepOwnership x = new DeepOwnership(); x = global; x.next = null; } void FN_reassignPathToGlobalBad() { DeepOwnership x = new DeepOwnership(); x.next = global; x.next.next = null; } void deepIntraOk(){ DeepOwnership x = new DeepOwnership(); x.next.next = null; // doesn't warn here } void deepInterOk(){ DeepOwnership x = new DeepOwnership(); deepPrivate(x.next); } private void deepPrivate(DeepOwnership y){ y.next = null; } DeepOwnership deepFromOwnedThisOk(){ return new DeepOwnership(); } DeepOwnership arr[]; DeepOwnership(){ next.next = null; arr[0] = null; } private void loseOwnershipOfNext() { synchronized (this) { this.next = global; } } void FN_loseOwnershipInCalleeBad() { DeepOwnership x = new DeepOwnership(); x.next = new DeepOwnership(); loseOwnershipOfNext(); x.next.next = null; // doesn't warn here } }