in src/main/java/org/apache/bcel/verifier/statics/Pass2Verifier.java [443:483]
public void visitConstantValue(final ConstantValue obj) {// vmspec2 4.7.2
// Despite its name, this really is an Attribute,
// not a constant!
checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
final String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
if (!name.equals("ConstantValue")) {
throw new ClassConstraintException(
"The ConstantValue attribute '" + tostring(obj) + "' is not correctly named 'ConstantValue' but '" + name + "'.");
}
final Object pred = carrier.predecessor();
if (pred instanceof Field) { // ConstantValue attributes are quite senseless if the predecessor is not a field.
final Field f = (Field) pred;
// Field constraints have been checked before -- so we are safe using their type information.
final Type fieldType = Type.getType(((ConstantUtf8) cp.getConstant(f.getSignatureIndex())).getBytes());
final int index = obj.getConstantValueIndex();
if (index < 0 || index >= cplen) {
throw new ClassConstraintException("Invalid index '" + index + "' used by '" + tostring(obj) + "'.");
}
final Constant c = cp.getConstant(index);
if (CONST_Long.isInstance(c) && fieldType.equals(Type.LONG) || CONST_Float.isInstance(c) && fieldType.equals(Type.FLOAT)) {
return;
}
if (CONST_Double.isInstance(c) && fieldType.equals(Type.DOUBLE)) {
return;
}
if (CONST_Integer.isInstance(c) && (fieldType.equals(Type.INT) || fieldType.equals(Type.SHORT) || fieldType.equals(Type.CHAR)
|| fieldType.equals(Type.BYTE) || fieldType.equals(Type.BOOLEAN))) {
return;
}
if (CONST_String.isInstance(c) && fieldType.equals(Type.STRING)) {
return;
}
throw new ClassConstraintException("Illegal type of ConstantValue '" + obj + "' embedding Constant '" + c + "'. It is referenced by field '"
+ tostring(f) + "' expecting a different type: '" + fieldType + "'.");
}
}