public void visitINVOKESPECIAL()

in src/main/java/org/apache/bcel/verifier/structurals/InstConstraintVisitor.java [1678:1728]


    public void visitINVOKESPECIAL(final INVOKESPECIAL o) {
        try {
            // Don't init an object twice.
            if (o.getMethodName(cpg).equals(Const.CONSTRUCTOR_NAME) && !(stack().peek(o.getArgumentTypes(cpg).length) instanceof UninitializedObjectType)) {
                constraintViolated(o,
                    "Possibly initializing object twice."
                        + " A valid instruction sequence must not have an uninitialized object on the operand stack or in a local variable"
                        + " during a backwards branch, or in a local variable in code protected by an exception handler."
                        + " Please see The Java Virtual Machine Specification, Second Edition, 4.9.4 (pages 147 and 148) for details.");
            }

            // the o.getClassType(cpg) type has passed pass 2; see visitLoadClass(o).

            final int nargs = visitInvokeInternals(o);
            Type objref = stack().peek(nargs);
            if (objref == Type.NULL) {
                return;
            }
            if (!(objref instanceof ReferenceType)) {
                constraintViolated(o, "Expecting a reference type as 'objectref' on the stack, not a '" + objref + "'.");
            }
            String objRefClassName = null;
            if (!o.getMethodName(cpg).equals(Const.CONSTRUCTOR_NAME)) {
                referenceTypeIsInitialized(o, (ReferenceType) objref);
                if (!(objref instanceof ObjectType)) {
                    if (!(objref instanceof ArrayType)) { // could be a ReturnaddressType
                        constraintViolated(o, "Expecting an ObjectType as 'objectref' on the stack, not a '" + objref + "'.");
                    } else {
                        objref = GENERIC_ARRAY;
                    }
                }

                objRefClassName = ((ObjectType) objref).getClassName();
            } else {
                if (!(objref instanceof UninitializedObjectType)) {
                    constraintViolated(o, "Expecting an UninitializedObjectType as 'objectref' on the stack, not a '" + objref
                        + "'. Otherwise, you couldn't invoke a method since an array has no methods (not to speak of a return address).");
                }
                objRefClassName = ((UninitializedObjectType) objref).getInitialized().getClassName();
            }

            final String theClass = o.getClassName(cpg);
            if (!Repository.instanceOf(objRefClassName, theClass)) {
                constraintViolated(o, "The 'objref' item '" + objref + "' does not implement '" + theClass + "' as expected.");
            }

        } catch (final ClassNotFoundException e) {
            // FIXME: maybe not the best way to handle this
            throw new AssertionViolatedException("Missing class: " + e, e);
        }
    }