@Override
  protected String declareConversionFunction(
      final ILocation loc, final CPrimitive oldType, final CPrimitive newType) {

    final String functionName = "convert" + oldType.toString() + "To" + newType.toString();
    final String prefixedFunctionName = "~" + functionName;
    if (!mFunctionDeclarations.getDeclaredFunctions().containsKey(prefixedFunctionName)) {

      final Attribute[] attributes;
      final ASTType paramASTType = mTypeHandler.ctype2asttype(loc, oldType);
      if (newType.isFloatingType()) {
        attributes =
            generateAttributes(loc, mOverapproximateFloatingPointOperations, "to_real", null);
      } else if (newType.isIntegerType()) {
        attributes =
            generateAttributes(loc, mOverapproximateFloatingPointOperations, "to_int", null);
      } else {
        throw new AssertionError("unhandled case");
      }
      final ASTType[] params = new ASTType[] {paramASTType};
      final ASTType resultASTType = mTypeHandler.ctype2asttype(loc, newType);

      mFunctionDeclarations.declareFunction(
          loc, prefixedFunctionName, attributes, resultASTType, params);
    }
    return prefixedFunctionName;
  }
 private Expression constructUnaryIntExprMinus(
     final ILocation loc, final Expression expr, final CPrimitive type) {
   if (type.getGeneralType() == CPrimitiveCategory.INTTYPE) {
     return ExpressionFactory.newUnaryExpression(
         loc, UnaryExpression.Operator.ARITHNEGATIVE, expr);
   } else if (type.getGeneralType() == CPrimitiveCategory.FLOATTYPE) {
     // TODO: having boogie deal with negative real literals would be the nice solution..
     return ExpressionFactory.newBinaryExpression(
         loc, Operator.ARITHMINUS, new RealLiteral(loc, "0.0"), expr);
   } else {
     throw new IllegalArgumentException("unsupported " + type);
   }
 }
 @Override
 public Expression constructArithmeticFloatingPointExpression(
     final ILocation loc,
     final int nodeOperator,
     final Expression exp1,
     final CPrimitive type1,
     final Expression exp2,
     final CPrimitive type2) {
   if (mOverapproximateFloatingPointOperations) {
     final String functionName = "someBinaryArithmetic" + type1.toString() + "operation";
     final String prefixedFunctionName = "~" + functionName;
     if (!mFunctionDeclarations.getDeclaredFunctions().containsKey(prefixedFunctionName)) {
       final Attribute attribute =
           new NamedAttribute(
               loc,
               FunctionDeclarations.s_OVERAPPROX_IDENTIFIER,
               new Expression[] {new StringLiteral(loc, functionName)});
       final Attribute[] attributes = new Attribute[] {attribute};
       final ASTType astType = mTypeHandler.ctype2asttype(loc, type1);
       mFunctionDeclarations.declareFunction(
           loc, prefixedFunctionName, attributes, astType, astType, astType);
     }
     return new FunctionApplication(loc, prefixedFunctionName, new Expression[] {exp1, exp2});
   } else {
     return constructArithmeticExpression(loc, nodeOperator, exp1, exp2);
   }
 }
 public void oldConvertPointerToInt(
     final ILocation loc, final ExpressionResult rexp, final CPrimitive newType) {
   assert newType.isIntegerType();
   assert rexp.lrVal.getCType() instanceof CPointer;
   if (OVERAPPROXIMATE_INT_POINTER_CONVERSION) {
     super.convertPointerToInt(loc, rexp, newType);
   } else {
     final Expression pointerExpression = rexp.lrVal.getValue();
     final Expression intExpression;
     if (mTypeSizes.useFixedTypeSizes()) {
       final BigInteger maxPtrValuePlusOne = mTypeSizes.getMaxValueOfPointer().add(BigInteger.ONE);
       final IntegerLiteral maxPointer = new IntegerLiteral(loc, maxPtrValuePlusOne.toString());
       intExpression =
           constructArithmeticExpression(
               loc,
               IASTBinaryExpression.op_plus,
               constructArithmeticExpression(
                   loc,
                   IASTBinaryExpression.op_multiply,
                   MemoryHandler.getPointerBaseAddress(pointerExpression, loc),
                   newType,
                   maxPointer,
                   newType),
               newType,
               MemoryHandler.getPointerOffset(pointerExpression, loc),
               newType);
     } else {
       intExpression = MemoryHandler.getPointerOffset(pointerExpression, loc);
     }
     final RValue rValue = new RValue(intExpression, newType, false, true);
     rexp.lrVal = rValue;
   }
 }
 @Override
 public void convertIntToInt_NonBool(
     final ILocation loc, final ExpressionResult operand, final CPrimitive resultType) {
   if (resultType.isIntegerType()) {
     convertToIntegerType(loc, operand, resultType);
   } else {
     throw new UnsupportedOperationException("not yet supported: conversion to " + resultType);
   }
 }
  @Override
  public Expression constructBinaryComparisonFloatingPointExpression(
      final ILocation loc,
      final int nodeOperator,
      final Expression exp1,
      final CPrimitive type1,
      final Expression exp2,
      final CPrimitive type2) {
    if (mOverapproximateFloatingPointOperations) {
      final String functionName = "someBinary" + type1.toString() + "ComparisonOperation";
      final String prefixedFunctionName = "~" + functionName;
      if (!mFunctionDeclarations.getDeclaredFunctions().containsKey(prefixedFunctionName)) {
        final Attribute attribute =
            new NamedAttribute(
                loc,
                FunctionDeclarations.s_OVERAPPROX_IDENTIFIER,
                new Expression[] {new StringLiteral(loc, functionName)});
        final Attribute[] attributes = new Attribute[] {attribute};
        final ASTType paramAstType = mTypeHandler.ctype2asttype(loc, type1);
        final ASTType resultAstType = new PrimitiveType(loc, SFO.BOOL);
        mFunctionDeclarations.declareFunction(
            loc, prefixedFunctionName, attributes, resultAstType, paramAstType, paramAstType);
      }
      return new FunctionApplication(loc, prefixedFunctionName, new Expression[] {exp1, exp2});
    } else {
      BinaryExpression.Operator op;
      switch (nodeOperator) {
        case IASTBinaryExpression.op_equals:
          op = BinaryExpression.Operator.COMPEQ;
          break;
        case IASTBinaryExpression.op_greaterEqual:
          op = BinaryExpression.Operator.COMPGEQ;
          break;
        case IASTBinaryExpression.op_greaterThan:
          op = BinaryExpression.Operator.COMPGT;
          break;
        case IASTBinaryExpression.op_lessEqual:
          op = BinaryExpression.Operator.COMPLEQ;
          break;
        case IASTBinaryExpression.op_lessThan:
          op = BinaryExpression.Operator.COMPLT;
          break;
        case IASTBinaryExpression.op_notequals:
          op = BinaryExpression.Operator.COMPNEQ;
          break;
        default:
          throw new AssertionError("Unknown BinaryExpression operator " + nodeOperator);
      }

      return ExpressionFactory.newBinaryExpression(loc, op, exp1, exp2);
    }
  }
  @Override
  public Expression constructBinaryComparisonIntegerExpression(
      final ILocation loc,
      final int nodeOperator,
      final Expression exp1,
      final CPrimitive type1,
      final Expression exp2,
      final CPrimitive type2) {
    if (!type1.equals(type2)) {
      throw new IllegalArgumentException("incompatible types " + type1 + " and " + type2);
    }
    Expression leftExpr = exp1;
    Expression rightExpr = exp2;
    if (mUnsignedTreatment == UnsignedTreatment.WRAPAROUND && mTypeSizes.isUnsigned(type1)) {
      assert mTypeSizes.isUnsigned(type2);
      leftExpr = applyWraparound(loc, mTypeSizes, type1, leftExpr);
      rightExpr = applyWraparound(loc, mTypeSizes, type2, rightExpr);
    }
    BinaryExpression.Operator op;
    switch (nodeOperator) {
      case IASTBinaryExpression.op_equals:
        op = BinaryExpression.Operator.COMPEQ;
        break;
      case IASTBinaryExpression.op_greaterEqual:
        op = BinaryExpression.Operator.COMPGEQ;
        break;
      case IASTBinaryExpression.op_greaterThan:
        op = BinaryExpression.Operator.COMPGT;
        break;
      case IASTBinaryExpression.op_lessEqual:
        op = BinaryExpression.Operator.COMPLEQ;
        break;
      case IASTBinaryExpression.op_lessThan:
        op = BinaryExpression.Operator.COMPLT;
        break;
      case IASTBinaryExpression.op_notequals:
        op = BinaryExpression.Operator.COMPNEQ;
        break;
      default:
        throw new AssertionError("Unknown BinaryExpression operator " + nodeOperator);
    }

    return ExpressionFactory.newBinaryExpression(loc, op, leftExpr, rightExpr);
  }
 public static Expression applyWraparound(
     final ILocation loc,
     final TypeSizes typeSizes,
     final CPrimitive cPrimitive,
     final Expression operand) {
   if (cPrimitive.getGeneralType() == CPrimitiveCategory.INTTYPE) {
     if (typeSizes.isUnsigned(cPrimitive)) {
       final BigInteger maxValuePlusOne =
           typeSizes.getMaxValueOfPrimitiveType(cPrimitive).add(BigInteger.ONE);
       return ExpressionFactory.newBinaryExpression(
           loc,
           BinaryExpression.Operator.ARITHMOD,
           operand,
           new IntegerLiteral(loc, maxValuePlusOne.toString()));
     } else {
       throw new AssertionError("wraparound only for unsigned types");
     }
   } else {
     throw new AssertionError("wraparound only for integer types");
   }
 }
  private void convertToIntegerType(
      final ILocation loc, final ExpressionResult operand, final CPrimitive resultType) {
    assert resultType.isIntegerType();
    final CPrimitive oldType = (CPrimitive) operand.lrVal.getCType();
    if (oldType.isIntegerType()) {
      final Expression newExpression;
      if (mTypeSizes.isUnsigned(resultType)) {
        final Expression oldWrappedIfNeeded;
        if (mTypeSizes.isUnsigned(oldType)
            && mTypeSizes.getSize(resultType.getType()) > mTypeSizes.getSize(oldType.getType())) {
          // required for sound Nutz transformation
          // (see examples/programs/regression/c/NutzTransformation03.c)
          oldWrappedIfNeeded = applyWraparound(loc, mTypeSizes, oldType, operand.lrVal.getValue());
        } else {
          oldWrappedIfNeeded = operand.lrVal.getValue();
        }
        if (mUnsignedTreatment == UnsignedTreatment.ASSERT) {
          final BigInteger maxValuePlusOne =
              mTypeSizes.getMaxValueOfPrimitiveType(resultType).add(BigInteger.ONE);
          final AssertStatement assertGeq0 =
              new AssertStatement(
                  loc,
                  ExpressionFactory.newBinaryExpression(
                      loc,
                      BinaryExpression.Operator.COMPGEQ,
                      oldWrappedIfNeeded,
                      new IntegerLiteral(loc, SFO.NR0)));
          final Check chk1 = new Check(Spec.UINT_OVERFLOW);
          chk1.addToNodeAnnot(assertGeq0);
          operand.stmt.add(assertGeq0);

          final AssertStatement assertLtMax =
              new AssertStatement(
                  loc,
                  ExpressionFactory.newBinaryExpression(
                      loc,
                      BinaryExpression.Operator.COMPLT,
                      oldWrappedIfNeeded,
                      new IntegerLiteral(loc, maxValuePlusOne.toString())));
          final Check chk2 = new Check(Spec.UINT_OVERFLOW);
          chk2.addToNodeAnnot(assertLtMax);
          operand.stmt.add(assertLtMax);
        } else {
          // do nothing
        }
        newExpression = oldWrappedIfNeeded;
      } else {
        assert !mTypeSizes.isUnsigned(resultType);
        final Expression oldWrappedIfUnsigned;
        if (mTypeSizes.isUnsigned(oldType)) {
          // required for sound Nutz transformation
          // (see examples/programs/regression/c/NutzTransformation01.c)
          oldWrappedIfUnsigned =
              applyWraparound(loc, mTypeSizes, oldType, operand.lrVal.getValue());
        } else {
          oldWrappedIfUnsigned = operand.lrVal.getValue();
        }
        if (mTypeSizes.getSize(resultType.getType()) > mTypeSizes.getSize(oldType.getType())
            || (mTypeSizes
                    .getSize(resultType.getType())
                    .equals(mTypeSizes.getSize(oldType.getType()))
                && !mTypeSizes.isUnsigned(oldType))) {
          newExpression = oldWrappedIfUnsigned;
        } else {
          // According to C11 6.3.1.3.3 the result is implementation-defined
          // it the value cannot be represented by the new type
          // We have chosen an implementation that is similar to
          // taking the lowest bits in a two's complement representation:
          // First we take the value modulo the cardinality of the
          // data range (which is 2*(MAX_VALUE+1) for signed )
          // If the number is strictly larger than MAX_VALUE we
          // subtract the cardinality of the data range.
          final CPrimitive correspondingUnsignedType =
              mTypeSizes.getCorrespondingUnsignedType(resultType);
          final Expression wrapped =
              applyWraparound(loc, mTypeSizes, correspondingUnsignedType, oldWrappedIfUnsigned);
          final Expression maxValue =
              constructLiteralForIntegerType(
                  loc, oldType, mTypeSizes.getMaxValueOfPrimitiveType(resultType));
          final Expression condition =
              ExpressionFactory.newBinaryExpression(loc, Operator.COMPLEQ, wrapped, maxValue);
          final Expression range =
              constructLiteralForIntegerType(
                  loc,
                  oldType,
                  mTypeSizes
                      .getMaxValueOfPrimitiveType(correspondingUnsignedType)
                      .add(BigInteger.ONE));
          newExpression =
              ExpressionFactory.newIfThenElseExpression(
                  loc,
                  condition,
                  wrapped,
                  ExpressionFactory.newBinaryExpression(loc, Operator.ARITHMINUS, wrapped, range));
        }
      }
      final RValue newRValue = new RValue(newExpression, resultType, false, false);
      operand.lrVal = newRValue;
    } else {
      throw new UnsupportedOperationException("not yet supported: conversion from " + oldType);
    }
  }
Esempio n. 10
0
  @Override
  public Expression constructArithmeticIntegerExpression(
      final ILocation loc,
      final int nodeOperator,
      final Expression leftExp,
      final CPrimitive leftType,
      final Expression rightExp,
      final CPrimitive rightType) {
    assert leftType.getGeneralType() == CPrimitiveCategory.INTTYPE;
    assert rightType.getGeneralType() == CPrimitiveCategory.INTTYPE;

    Expression leftExpr = leftExp;
    Expression rightExpr = rightExp;
    if (leftType.isIntegerType() && mTypeSizes.isUnsigned(leftType)) {
      assert rightType.isIntegerType() && mTypeSizes.isUnsigned(rightType) : "incompatible types";
      if (nodeOperator == IASTBinaryExpression.op_divide
          || nodeOperator == IASTBinaryExpression.op_divideAssign
          || nodeOperator == IASTBinaryExpression.op_modulo
          || nodeOperator == IASTBinaryExpression.op_moduloAssign) {
        // apply wraparound to ensure that Nutz transformation is sound
        // (see examples/programs/regression/c/NutzTransformation02.c)
        leftExpr = applyWraparound(loc, mTypeSizes, leftType, leftExpr);
        rightExpr = applyWraparound(loc, mTypeSizes, rightType, rightExpr);
      }
    }
    final boolean bothAreIntegerLiterals =
        leftExpr instanceof IntegerLiteral && rightExpr instanceof IntegerLiteral;
    BigInteger leftValue = null;
    BigInteger rightValue = null;
    // TODO: add checks for UnaryExpression (otherwise we don't catch negative constants, here) -->
    // or remove all
    // the cases
    // (if-then-else conditions are checked for being constant in RCFGBuilder anyway, so this is
    // merely a decision
    // of readability of Boogie code..)
    if (leftExpr instanceof IntegerLiteral) {
      leftValue = new BigInteger(((IntegerLiteral) leftExpr).getValue());
    }
    if (rightExpr instanceof IntegerLiteral) {
      rightValue = new BigInteger(((IntegerLiteral) rightExpr).getValue());
    }
    switch (nodeOperator) {
      case IASTBinaryExpression.op_minusAssign:
      case IASTBinaryExpression.op_minus:
      case IASTBinaryExpression.op_multiplyAssign:
      case IASTBinaryExpression.op_multiply:
      case IASTBinaryExpression.op_plusAssign:
      case IASTBinaryExpression.op_plus:
        return constructArithmeticExpression(loc, nodeOperator, leftExp, rightExp);
      case IASTBinaryExpression.op_divideAssign:
      case IASTBinaryExpression.op_divide:
        return constructArIntExprDiv(
            loc, leftExpr, rightExpr, bothAreIntegerLiterals, leftValue, rightValue);
      case IASTBinaryExpression.op_moduloAssign:
      case IASTBinaryExpression.op_modulo:
        return constructArIntExprMod(
            loc, leftExpr, rightExpr, bothAreIntegerLiterals, leftValue, rightValue);
      default:
        final String msg = "Unknown or unsupported arithmetic expression";
        throw new UnsupportedSyntaxException(loc, msg);
    }
  }