public void visitINVOKESPECIAL()

in src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java [525:575]


        public void visitINVOKESPECIAL(final INVOKESPECIAL o) {
            try {
                // INVOKESPECIAL is a LoadClass; the Class where the referenced method is declared in,
                // is therefore resolved/verified.
                // INVOKESPECIAL is an InvokeInstruction, the argument and return types are resolved/verified,
                // too. So are the allowed method names.
                final String className = o.getClassName(constantPoolGen);
                final JavaClass jc = Repository.lookupClass(className);
                final Method m = getMethodRecursive(jc, o);
                if (m == null) {
                    constraintViolated(o, "Referenced method '" + o.getMethodName(constantPoolGen) + "' with expected signature '"
                        + o.getSignature(constantPoolGen) + "' not found in class '" + jc.getClassName() + "'.");
                }

                JavaClass current = Repository.lookupClass(verifier.getClassName());
                if (current.isSuper() && Repository.instanceOf(current, jc) && !current.equals(jc)
                    && !o.getMethodName(constantPoolGen).equals(Const.CONSTRUCTOR_NAME)) {
                    // Special lookup procedure for ACC_SUPER classes.

                    int supidx = -1;

                    Method meth = null;
                    while (supidx != 0) {
                        supidx = current.getSuperclassNameIndex();
                        current = Repository.lookupClass(current.getSuperclassName());

                        final Method[] meths = current.getMethods();
                        for (final Method meth2 : meths) {
                            if (meth2.getName().equals(o.getMethodName(constantPoolGen))
                                && Type.getReturnType(meth2.getSignature()).equals(o.getReturnType(constantPoolGen))
                                && Arrays.equals(Type.getArgumentTypes(meth2.getSignature()), o.getArgumentTypes(constantPoolGen))) {
                                meth = meth2;
                                break;
                            }
                        }
                        if (meth != null) {
                            break;
                        }
                    }
                    if (meth == null) {
                        constraintViolated(o, "ACC_SUPER special lookup procedure not successful: method '" + o.getMethodName(constantPoolGen)
                            + "' with proper signature not declared in superclass hierarchy.");
                    }
                }

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

        }