コード例 #1
0
 @Override
 public Region[] visit(final CBinaryExpression pE) {
   final Region[] lVal = pE.getOperand1().accept(this);
   final Region[] rVal = pE.getOperand2().accept(this);
   if (lVal == null || rVal == null) {
     return null;
   }
   return calculateBinaryOperation(lVal, rVal, bvmgr, pE, machineModel);
 }
コード例 #2
0
  /**
   * This method calculates the exact result for a binary operation.
   *
   * @param lVal first operand
   * @param rVal second operand
   * @param machineModel information about types
   */
  public static Region[] calculateBinaryOperation(
      Region[] lVal,
      Region[] rVal,
      final BitvectorManager bvmgr,
      final CBinaryExpression binaryExpr,
      final MachineModel machineModel) {

    final BinaryOperator binaryOperator = binaryExpr.getOperator();
    final CType calculationType = binaryExpr.getCalculationType();

    lVal = castCValue(lVal, calculationType, bvmgr, machineModel);
    if (binaryOperator != BinaryOperator.SHIFT_LEFT
        && binaryOperator != BinaryOperator.SHIFT_RIGHT) {
      /* For SHIFT-operations we do not cast the second operator.
       * We even do not need integer-promotion,
       * because the maximum SHIFT of 64 is lower than MAX_CHAR.
       *
       * ISO-C99 (6.5.7 #3): Bitwise shift operators
       * The integer promotions are performed on each of the operands.
       * The type of the result is that of the promoted left operand.
       * If the value of the right operand is negative or is greater than
       * or equal to the width of the promoted left operand,
       * the behavior is undefined.
       */
      rVal = castCValue(rVal, calculationType, bvmgr, machineModel);
    }

    Region[] result;
    switch (binaryOperator) {
      case PLUS:
      case MINUS:
      case DIVIDE:
      case MODULO:
      case MULTIPLY:
      case SHIFT_LEFT:
      case SHIFT_RIGHT:
      case BINARY_AND:
      case BINARY_OR:
      case BINARY_XOR:
        {
          result =
              arithmeticOperation(lVal, rVal, bvmgr, binaryOperator, calculationType, machineModel);
          result = castCValue(result, binaryExpr.getExpressionType(), bvmgr, machineModel);

          break;
        }

      case EQUALS:
      case NOT_EQUALS:
      case GREATER_THAN:
      case GREATER_EQUAL:
      case LESS_THAN:
      case LESS_EQUAL:
        {
          final Region tmp =
              booleanOperation(lVal, rVal, bvmgr, binaryOperator, calculationType, machineModel);
          // return 1 if expression holds, 0 otherwise

          int size = 32;
          if (calculationType instanceof CSimpleType) {
            final CSimpleType st = (CSimpleType) calculationType;
            if (st.getType() == CBasicType.INT || st.getType() == CBasicType.CHAR) {
              final int bitPerByte = machineModel.getSizeofCharInBits();
              final int numBytes = machineModel.getSizeof(st);
              size = bitPerByte * numBytes;
            }
          }

          result = bvmgr.wrapLast(tmp, size);
          // we do not cast here, because 0 and 1 should be small enough for every type.

          break;
        }

      default:
        throw new AssertionError("unhandled binary operator");
    }

    return result;
  }