if (!(throwType instanceof ObjectType)) throw new DataflowAnalysisException("Non object type thrown by " + pei); exceptionTypeSet.addExplicit((ObjectType) throwType);
if (throwType instanceof ObjectType) { exceptionTypeSet.addExplicit((ObjectType) throwType); } else if (throwType instanceof ExceptionObjectType) { exceptionTypeSet.addAll(((ExceptionObjectType)throwType).getExceptionSet()); } else { throw new DataflowAnalysisException("Non object type " + throwType + " thrown by " + pei + " in " + SignatureConverter.convertMethodSignature(methodGen)); }
	private ExceptionSet enumerateExceptionTypes(BasicBlock basicBlock)		throws ClassNotFoundException, DataflowAnalysisException {		ExceptionSet exceptionTypeSet = new ExceptionSet();		InstructionHandle pei = basicBlock.getExceptionThrower();		Instruction ins = pei.getInstruction();		// Get the exceptions that BCEL knows about.		// Note that all of these are unchecked.		ExceptionThrower exceptionThrower = (ExceptionThrower) ins;		Class[] exceptionList = exceptionThrower.getExceptions();		for (int i = 0; i < exceptionList.length; ++i) {			exceptionTypeSet.addImplicit(new ObjectType(exceptionList[i].getName()));		}		// Assume that an Error may be thrown by any instruction.		exceptionTypeSet.addImplicit(Hierarchy.ERROR_TYPE);		if (ins instanceof ATHROW) {			// For ATHROW instructions, we generate *two* blocks			// for which the ATHROW is an exception thrower.			//			// - The first, empty basic block, does the null check			// - The second block, which actually contains the ATHROW,			//   throws the object on the top of the operand stack			//			// We make a special case of the block containing the ATHROW,			// by removing all of the implicit exceptions,			// and using type information to figure out what is thrown.			if (basicBlock.containsInstruction(pei)) {				// This is the actual ATHROW, not the null check				// and implicit exceptions.				exceptionTypeSet.clear();				TypeFrame frame = typeDataflow.getFactAtLocation(new Location(pei, basicBlock));					// Check whether or not the frame is valid.				// Sun's javac sometimes emits unreachable code.				// For example, it will emit code that follows a JSR				// subroutine call that never returns.				// If the frame is invalid, then we can just make				// a conservative assumption that anything could be				// thrown at this ATHROW.				if (!frame.isValid()) {					exceptionTypeSet.addExplicit(Type.THROWABLE);				} else {					Type throwType = frame.getTopValue();					if (!(throwType instanceof ObjectType))						throw new DataflowAnalysisException("Non object type thrown by " + pei);					exceptionTypeSet.addExplicit((ObjectType) throwType);				}			}		}		// If it's an InvokeInstruction, add declared exceptions and RuntimeException		if (ins instanceof InvokeInstruction) {			InvokeInstruction inv = (InvokeInstruction) ins;			ObjectType[] declaredExceptionList = Hierarchy.findDeclaredExceptions(inv, cpg);			if (declaredExceptionList == null) {				// Couldn't find declared exceptions,				// so conservatively assume it could thrown any checked exception.				if (DEBUG) System.out.println("Couldn't find declared exceptions for " +					SignatureConverter.convertMethodSignature(inv, cpg));				exceptionTypeSet.addExplicit(Hierarchy.EXCEPTION_TYPE);			} else {				for (int i = 0; i < declaredExceptionList.length; ++i) {					exceptionTypeSet.addExplicit(declaredExceptionList[i]);				}			}			exceptionTypeSet.addImplicit(Hierarchy.RUNTIME_EXCEPTION_TYPE);		}		if (DEBUG) System.out.println(pei + " can throw " + exceptionTypeSet);		return exceptionTypeSet;	}