Exemplo n.º 1
0
 public void analysisSkippedDueToInvokeDynamic(XMethod m) {
   if (!m.usesInvokeDynamic()) {
     throw new IllegalArgumentException();
   }
   if (skippedDueToInvokeDynamic.add(m.getMethodDescriptor())) {
     logAnError(m + " skipped due to invoke_dynamic");
   }
 }
 public static boolean assertsFirstParameterIsNonnull(XMethod m) {
   return (m.getName().equalsIgnoreCase("checkNonNull")
           || m.getName().equalsIgnoreCase("checkNotNull")
           // JDK 7 java.util.Objects.requireNonNull(Object)
           || m.getName().equals("requireNonNull")
           // org.eclipse.core.runtime.Assert(Object)
           || m.getName().equalsIgnoreCase("isNotNull")
           || m.getName().equalsIgnoreCase("assertNotNull"))
       && m.getSignature().startsWith("(Ljava/lang/Object;");
 }
  /**
   * Constructor.
   *
   * @param method an XMethod specifying a specific method in a specific class
   * @throws ClassNotFoundException
   */
  public JavaClassAndMethod(XMethod method) throws ClassNotFoundException {

    this.javaClass = Repository.lookupClass(method.getClassName());
    for (Method m : javaClass.getMethods())
      if (m.getName().equals(method.getName())
          && m.getSignature().equals(method.getSignature())
          && m.isStatic() == method.isStatic()) {
        this.method = m;
        return;
      }
    throw new IllegalArgumentException("Can't find " + method);
  }
  public boolean parameterMustBeNonNull(XMethod m, int param) {
    if (param == 0) {
      if (m.getName().equals("equals")
          && m.getSignature().equals("(Ljava/lang/Object;)Z")
          && !m.isStatic()) return false;
      else if (m.getName().equals("main")
          && m.getSignature().equals("([Ljava/lang/String;)V")
          && m.isStatic()
          && m.isPublic()) return true;
      else if (assertsFirstParameterIsNonnull(m)) return true;
      else if (m.getName().equals("compareTo") && m.getSignature().endsWith(";)Z") && !m.isStatic())
        return true;
    }
    if (!anyAnnotations(NullnessAnnotation.NONNULL)) return false;
    XMethodParameter xmp = new XMethodParameter(m, param);
    NullnessAnnotation resolvedAnnotation = getResolvedAnnotation(xmp, true);

    return resolvedAnnotation == NullnessAnnotation.NONNULL;
  }
 /**
  * Return whether or not the given method is concrete.
  *
  * @param xmethod the method
  * @return true if the method is concrete, false otherwise
  */
 @Deprecated
 public static boolean isConcrete(XMethod xmethod) {
   int accessFlags = xmethod.getAccessFlags();
   return (accessFlags & Constants.ACC_ABSTRACT) == 0 && (accessFlags & Constants.ACC_NATIVE) == 0;
 }
  /**
   * Resolve possible instance method call targets.
   *
   * @param receiverType type of the receiver object
   * @param invokeInstruction the InvokeInstruction
   * @param cpg the ConstantPoolGen
   * @param receiverTypeIsExact if true, the receiver type is known exactly, which should allow a
   *     precise result
   * @return Set of methods which might be called
   * @throws ClassNotFoundException
   */
  public static Set<JavaClassAndMethod> resolveMethodCallTargets(
      ReferenceType receiverType,
      InvokeInstruction invokeInstruction,
      ConstantPoolGen cpg,
      boolean receiverTypeIsExact)
      throws ClassNotFoundException {
    HashSet<JavaClassAndMethod> result = new HashSet<JavaClassAndMethod>();

    if (invokeInstruction.getOpcode() == Constants.INVOKESTATIC)
      throw new IllegalArgumentException();

    String methodName = invokeInstruction.getName(cpg);
    String methodSig = invokeInstruction.getSignature(cpg);

    // Array method calls aren't virtual.
    // They should just resolve to Object methods.
    if (receiverType instanceof ArrayType) {
      JavaClass javaLangObject =
          AnalysisContext.currentAnalysisContext().lookupClass("java.lang.Object");
      JavaClassAndMethod classAndMethod =
          findMethod(javaLangObject, methodName, methodSig, INSTANCE_METHOD);
      if (classAndMethod != null) result.add(classAndMethod);
      return result;
    }

    if (receiverType instanceof NullType) {
      return Collections.<JavaClassAndMethod>emptySet();
    }
    AnalysisContext analysisContext = AnalysisContext.currentAnalysisContext();

    // Get the receiver class.
    String receiverClassName = ((ObjectType) receiverType).getClassName();
    JavaClass receiverClass = analysisContext.lookupClass(receiverClassName);
    ClassDescriptor receiverDesc =
        DescriptorFactory.createClassDescriptorFromDottedClassName(receiverClassName);

    // Figure out the upper bound for the method.
    // This is what will be called if this is not a virtual call site.
    JavaClassAndMethod upperBound =
        findMethod(receiverClass, methodName, methodSig, CONCRETE_METHOD);
    if (upperBound == null) {
      upperBound =
          findInvocationLeastUpperBound(
              receiverClass, methodName, methodSig, CONCRETE_METHOD, false);
    }
    if (upperBound != null) {
      if (DEBUG_METHOD_LOOKUP) {
        System.out.println(
            "Adding upper bound: "
                + SignatureConverter.convertMethodSignature(
                    upperBound.getJavaClass(), upperBound.getMethod()));
      }
      result.add(upperBound);
    }

    // Is this a virtual call site?
    boolean virtualCall =
        (invokeInstruction.getOpcode() == Constants.INVOKEVIRTUAL
                || invokeInstruction.getOpcode() == Constants.INVOKEINTERFACE)
            && (upperBound == null
                || !upperBound.getJavaClass().isFinal() && !upperBound.getMethod().isFinal())
            && !receiverTypeIsExact;

    if (virtualCall) {
      if (!receiverClassName.equals("java.lang.Object")) {

        // This is a true virtual call: assume that any concrete
        // subtype method may be called.
        Set<ClassDescriptor> subTypeSet = analysisContext.getSubtypes2().getSubtypes(receiverDesc);
        for (ClassDescriptor subtype : subTypeSet) {
          XMethod concreteSubtypeMethod = findMethod(subtype, methodName, methodSig, false);
          if (concreteSubtypeMethod != null
              && (concreteSubtypeMethod.getAccessFlags() & Constants.ACC_ABSTRACT) == 0) {
            result.add(new JavaClassAndMethod(concreteSubtypeMethod));
          }
        }
        if (false && subTypeSet.size() > 500)
          new RuntimeException(
                  receiverClassName
                      + " has "
                      + subTypeSet.size()
                      + " subclasses, "
                      + result.size()
                      + " of which implement "
                      + methodName
                      + methodSig
                      + " "
                      + invokeInstruction)
              .printStackTrace(System.out);
      }
    }
    return result;
  }
 public boolean choose(XMethod method) {
   return !method.isStatic();
 }
 public boolean choose(XMethod method) {
   return accessFlagsAreConcrete(method.getAccessFlags());
 }
  @CheckForNull
  @Override
  public NullnessAnnotation getResolvedAnnotation(final Object o, boolean getMinimal) {

    Profiler profiler = Global.getAnalysisCache().getProfiler();
    profiler.start(this.getClass());
    try {
      if (o instanceof XMethodParameter) {
        XMethodParameter mp = (XMethodParameter) o;
        XMethod m = mp.getMethod();
        // TODO: Handle argument to equals specially: generate special
        // bug code for it
        int parameterNumber = mp.getParameterNumber();
        if (parameterNumber == 0) {
          if (m.getName().equals("equals")
              && m.getSignature().equals("(Ljava/lang/Object;)Z")
              && !m.isStatic()) return NullnessAnnotation.CHECK_FOR_NULL;
          else if (m.getName().equals("main")
              && m.getSignature().equals("([Ljava/lang/String;)V")
              && m.isStatic()
              && m.isPublic()) return NullnessAnnotation.NONNULL;
          else if (assertsFirstParameterIsNonnull(m)) return NullnessAnnotation.NONNULL;
          else if (m.getName().equals("compareTo")
              && m.getSignature().endsWith(";)Z")
              && !m.isStatic()) return NullnessAnnotation.NONNULL;
        }
      } else if (o instanceof XMethod) {
        XMethod m = (XMethod) o;
        String name = m.getName();
        String signature = m.getSignature();
        if (!m.isStatic()
            && (name.equals("clone") && signature.equals("()Ljava/lang/Object;")
                || name.equals("toString") && signature.equals("()Ljava/lang/String;")
                || m.isPrivate()
                    && name.equals("readResolve")
                    && signature.equals("()Ljava/lang/Object;"))) {
          NullnessAnnotation result = super.getDirectAnnotation(m);
          if (result != null) return result;
          return NullnessAnnotation.NONNULL;
        }

      } else if (o instanceof XField) {
        XField f = (XField) o;
        if (f.getName().startsWith("this$")) return NullnessAnnotation.NONNULL;
      }
      NullnessAnnotation result = super.getResolvedAnnotation(o, getMinimal);
      return result;
    } finally {
      profiler.end(this.getClass());
    }
  }