We now warn when acquiring or releasing a scoped capability a second
time, not just if the underlying mutexes have been acquired or released
a second time.
Whether we unlock the underlying mutexes now depends on the status of
the scoped capability. So we don't unlock them if we are already
released, and we unlock them (with warning even on destruction) if we
are currently locked.
It's been a while since I last looked at this code, but I don't think you can use mutable fields in a FactEntry. The analysis creates a FactSet for each program point, but each FactSet simply has pointers (FactIDs) for the underlying FactEntries. If you change the definition of a FactEntry, it will change that definition for every program point. So if you do an unlock on one side of a branch, and change the underlying FactEntry to reflect that, then analysis will then think you have also done the unlock on the other side of the branch.
Any changes should always be done by adding or removing entries from the FactSet, not by mutating the underlying FactEntries.