blob: 5328a0d3d9800108c391525dbbb88359e5285bd2 [file] [log] [blame]
import org.checkerframework.checker.lock.qual.GuardSatisfied;
import org.checkerframework.checker.lock.qual.GuardedBy;
import org.checkerframework.checker.lock.qual.GuardedByBottom;
import org.checkerframework.checker.lock.qual.GuardedByUnknown;
public class Strings {
final Object lock = new Object();
// These casts are safe because if the casted Object is a String, it must be @GuardedBy({})
void StringIsGBnothing(
@GuardedByUnknown Object o1,
@GuardedBy("lock") Object o2,
@GuardSatisfied Object o3,
@GuardedByBottom Object o4) {
String s1 = (String) o1;
String s2 = (String) o2;
String s3 = (String) o3;
String s4 = (String) o4; // OK
}
// Tests that the resulting type of string concatenation is always @GuardedBy({})
// (and not @GuardedByUnknown, which is the LUB of @GuardedBy({}) (the type of the
// string literal "a") and @GuardedBy("lock") (the type of param))
void StringConcat(@GuardedBy("lock") MyClass param) {
{
String s1a = "a" + "a";
// :: error: (lock.not.held)
String s1b = "a" + param;
// :: error: (lock.not.held)
String s1c = param + "a";
// :: error: (lock.not.held)
String s1d = param.toString();
String s2 = "a";
// :: error: (lock.not.held)
s2 += param;
String s3 = "a";
// In addition to testing whether "lock" is held, tests that the result of a string
// concatenation has type @GuardedBy({}).
// :: error: (lock.not.held)
String s4 = s3 += param;
}
synchronized (lock) {
String s1a = "a" + "a";
String s1b = "a" + param;
String s1c = param + "a";
String s1d = param.toString();
String s2 = "a";
s2 += param;
String s3 = "a";
// In addition to testing whether "lock" is held, tests that the result of a string
// concatenation has type @GuardedBy({}).
String s4 = s3 += param;
}
}
class MyClass {
Object field = new Object();
}
}