String field_name = o.getFieldName(cpg);
JavaClass jc = Repository.lookupClass(o.getClassType(cpg).getClassName());
Field[] fields = jc.getFields();
Field f = null;
for (int i=0; i<fields.length; i++){
if (fields[i].getName().equals(field_name)){
f = fields[i];
break;
}
}
if (f == null){
throw new AssertionViolatedException("Field not found?!?");
}
Type value = stack().peek();
Type t = Type.getType(f.getSignature());
Type shouldbe = t;
if (shouldbe == Type.BOOLEAN ||
shouldbe == Type.BYTE ||
shouldbe == Type.CHAR ||
shouldbe == Type.SHORT){
shouldbe = Type.INT;
}
if (t instanceof ReferenceType){
ReferenceType rvalue = null;
if (value instanceof ReferenceType){
rvalue = (ReferenceType) value;
referenceTypeIsInitialized(o, rvalue);
}
else{
constraintViolated(o, "The stack top type '"+value+"' is not of a reference type as expected.");
}
// TODO: This can possibly only be checked using Staerk-et-al's "set-of-object types", not
// using "wider cast object types" created during verification.
// Comment it out if you encounter problems. See also the analogon at visitPUTSTATIC.
if (!(rvalue.isAssignmentCompatibleWith(shouldbe))){
constraintViolated(o, "The stack top type '"+value+"' is not assignment compatible with '"+shouldbe+"'.");
}
}
else{
if (shouldbe != value){
constraintViolated(o, "The stack top type '"+value+"' is not of type '"+shouldbe+"' as expected.");
}
}
if (f.isProtected()){
ObjectType classtype = o.getClassType(cpg);
ObjectType curr = new ObjectType(mg.getClassName());
if ( classtype.equals(curr) ||
curr.subclassOf(classtype) ){
Type tp = stack().peek(1);
if (tp == Type.NULL){
return;
}
if (! (tp instanceof ObjectType) ){
constraintViolated(o, "The 'objectref' must refer to an object that's not an array. Found instead: '"+tp+"'.");
}
ObjectType objreftype = (ObjectType) tp;
if (! ( objreftype.equals(curr) ||
objreftype.subclassOf(curr) ) ){
constraintViolated(o, "The referenced field has the ACC_PROTECTED modifier, and it's a member of the current class or a superclass of the current class. However, the referenced object type '"+stack().peek()+"' is not the current class or a subclass of the current class.");
}
}
}
// TODO: Could go into Pass 3a.
if (f.isStatic()){
constraintViolated(o, "Referenced field '"+f+"' is static which it shouldn't be.");
}
}