예제 #1
0
  @Override
  public Expression constructBinaryEqualityExpressionInteger(
      final ILocation loc,
      final int nodeOperator,
      final Expression exp1,
      final CType type1,
      final Expression exp2,
      final CType type2) {
    Expression leftExpr = exp1;
    Expression rightExpr = exp2;
    if ((type1 instanceof CPrimitive) && (type2 instanceof CPrimitive)) {
      final CPrimitive primitive1 = (CPrimitive) type1;
      final CPrimitive primitive2 = (CPrimitive) type2;
      if (mUnsignedTreatment == UnsignedTreatment.WRAPAROUND && mTypeSizes.isUnsigned(primitive1)) {
        assert mTypeSizes.isUnsigned(primitive2);
        leftExpr = applyWraparound(loc, mTypeSizes, primitive1, leftExpr);
        rightExpr = applyWraparound(loc, mTypeSizes, primitive2, rightExpr);
      }
    }

    if (nodeOperator == IASTBinaryExpression.op_equals) {
      return ExpressionFactory.newBinaryExpression(
          loc, BinaryExpression.Operator.COMPEQ, leftExpr, rightExpr);
    } else if (nodeOperator == IASTBinaryExpression.op_notequals) {
      return ExpressionFactory.newBinaryExpression(
          loc, BinaryExpression.Operator.COMPNEQ, leftExpr, rightExpr);
    } else {
      throw new IllegalArgumentException("operator is neither equals nor not equals");
    }
  }
예제 #2
0
 private Expression getLeftSmallerZeroAndThereIsRemainder(
     final ILocation loc, final Expression exp1, final Expression exp2) {
   final Expression leftModRight =
       ExpressionFactory.newBinaryExpression(loc, Operator.ARITHMOD, exp1, exp2);
   final Expression thereIsRemainder =
       ExpressionFactory.newBinaryExpression(
           loc, Operator.COMPNEQ, leftModRight, new IntegerLiteral(loc, SFO.NR0));
   final Expression leftSmallerZero =
       ExpressionFactory.newBinaryExpression(
           loc, BinaryExpression.Operator.COMPLT, exp1, new IntegerLiteral(loc, SFO.NR0));
   return ExpressionFactory.newBinaryExpression(
       loc, Operator.LOGICAND, leftSmallerZero, thereIsRemainder);
 }
예제 #3
0
 private Expression constructArithmeticExpression(
     final ILocation loc, final int nodeOperator, final Expression exp1, final Expression exp2) {
   final BinaryExpression.Operator operator;
   switch (nodeOperator) {
     case IASTBinaryExpression.op_minusAssign:
     case IASTBinaryExpression.op_minus:
       operator = Operator.ARITHMINUS;
       break;
     case IASTBinaryExpression.op_multiplyAssign:
     case IASTBinaryExpression.op_multiply:
       operator = Operator.ARITHMUL;
       break;
     case IASTBinaryExpression.op_divideAssign:
     case IASTBinaryExpression.op_divide:
       operator = Operator.ARITHDIV;
       break;
     case IASTBinaryExpression.op_moduloAssign:
     case IASTBinaryExpression.op_modulo:
       operator = Operator.ARITHMOD;
       break;
     case IASTBinaryExpression.op_plusAssign:
     case IASTBinaryExpression.op_plus:
       operator = Operator.ARITHPLUS;
       break;
     default:
       final String msg = "Unknown or unsupported arithmetic expression";
       throw new UnsupportedSyntaxException(loc, msg);
   }
   return ExpressionFactory.newBinaryExpression(loc, operator, exp1, exp2);
 }
예제 #4
0
  @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);
    }
  }
예제 #5
0
 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);
   }
 }
예제 #6
0
  @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);
  }
예제 #7
0
 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");
   }
 }
예제 #8
0
  /** Returns "assume (minValue <= lrValue && lrValue <= maxValue)" */
  private AssumeStatement constructAssumeInRangeStatement(
      final TypeSizes typeSizes,
      final ILocation loc,
      final Expression expr,
      final CPrimitive type) {
    final Expression minValue =
        constructLiteralForIntegerType(loc, type, typeSizes.getMinValueOfPrimitiveType(type));
    final Expression maxValue =
        constructLiteralForIntegerType(loc, type, typeSizes.getMaxValueOfPrimitiveType(type));

    final Expression biggerMinInt =
        constructBinaryComparisonExpression(
            loc, IASTBinaryExpression.op_lessEqual, minValue, type, expr, type);
    final Expression smallerMaxValue =
        constructBinaryComparisonExpression(
            loc, IASTBinaryExpression.op_lessEqual, expr, type, maxValue, type);
    final AssumeStatement inRange =
        new AssumeStatement(
            loc,
            ExpressionFactory.newBinaryExpression(
                loc, BinaryExpression.Operator.LOGICAND, biggerMinInt, smallerMaxValue));
    return inRange;
  }
예제 #9
0
  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);
    }
  }
예제 #10
0
 private Expression constructArIntExprMod(
     final ILocation loc,
     final Expression exp1,
     final Expression exp2,
     final boolean bothAreIntegerLiterals,
     final BigInteger leftValue,
     final BigInteger rightValue) {
   final BinaryExpression.Operator operator;
   operator = Operator.ARITHMOD;
   /*
    * In C the semantics of integer division is "rounding towards zero". In Boogie euclidian division is used. We
    * translate a % b into (a < 0 && a%b != 0) ? ( (b < 0) ? (a%b)-b : (a%b)+b) : a%b
    */
   // modulo on bigInteger does not seem to follow the "multiply, add, and get the result
   // back"-rule, together
   // with its division..
   if (bothAreIntegerLiterals) {
     final String constantResult;
     if (leftValue.signum() == 1 || leftValue.signum() == 0) {
       if (rightValue.signum() == 1) {
         constantResult = leftValue.mod(rightValue).toString();
       } else if (rightValue.signum() == -1) {
         constantResult = leftValue.mod(rightValue.negate()).toString();
       } else {
         constantResult = "0";
       }
     } else if (leftValue.signum() == -1) {
       if (rightValue.signum() == 1) {
         constantResult = (leftValue.negate().mod(rightValue)).negate().toString();
       } else if (rightValue.signum() == -1) {
         constantResult = (leftValue.negate().mod(rightValue.negate())).negate().toString();
       } else {
         constantResult = "0";
       }
     } else {
       throw new UnsupportedOperationException("constant is not assigned");
     }
     return new IntegerLiteral(loc, constantResult);
   } else {
     final Expression leftSmallerZeroAndThereIsRemainder =
         getLeftSmallerZeroAndThereIsRemainder(loc, exp1, exp2);
     final Expression rightSmallerZero =
         ExpressionFactory.newBinaryExpression(
             loc, BinaryExpression.Operator.COMPLT, exp2, new IntegerLiteral(loc, SFO.NR0));
     final Expression normalModulo =
         ExpressionFactory.newBinaryExpression(loc, operator, exp1, exp2);
     if (exp1 instanceof IntegerLiteral) {
       if (leftValue.signum() == 1) {
         return normalModulo;
       } else if (leftValue.signum() == -1) {
         return ExpressionFactory.newIfThenElseExpression(
             loc,
             rightSmallerZero,
             ExpressionFactory.newBinaryExpression(
                 loc, BinaryExpression.Operator.ARITHPLUS, normalModulo, exp2),
             ExpressionFactory.newBinaryExpression(
                 loc, BinaryExpression.Operator.ARITHMINUS, normalModulo, exp2));
       } else {
         return new IntegerLiteral(loc, SFO.NR0);
       }
     } else if (exp2 instanceof IntegerLiteral) {
       if (rightValue.signum() == 1 || rightValue.signum() == 0) {
         return ExpressionFactory.newIfThenElseExpression(
             loc,
             leftSmallerZeroAndThereIsRemainder,
             ExpressionFactory.newBinaryExpression(
                 loc, BinaryExpression.Operator.ARITHMINUS, normalModulo, exp2),
             normalModulo);
       } else if (rightValue.signum() == -1) {
         return ExpressionFactory.newIfThenElseExpression(
             loc,
             leftSmallerZeroAndThereIsRemainder,
             ExpressionFactory.newBinaryExpression(
                 loc, BinaryExpression.Operator.ARITHPLUS, normalModulo, exp2),
             normalModulo);
       }
       throw new UnsupportedOperationException(
           "Is it expected that this is a fall-through switch?");
     } else {
       return ExpressionFactory.newIfThenElseExpression(
           loc,
           leftSmallerZeroAndThereIsRemainder,
           ExpressionFactory.newIfThenElseExpression(
               loc,
               rightSmallerZero,
               ExpressionFactory.newBinaryExpression(
                   loc, BinaryExpression.Operator.ARITHPLUS, normalModulo, exp2),
               ExpressionFactory.newBinaryExpression(
                   loc, BinaryExpression.Operator.ARITHMINUS, normalModulo, exp2)),
           normalModulo);
     }
   }
 }
예제 #11
0
 private Expression constructArIntExprDiv(
     final ILocation loc,
     final Expression exp1,
     final Expression exp2,
     final boolean bothAreIntegerLiterals,
     final BigInteger leftValue,
     final BigInteger rightValue) {
   final BinaryExpression.Operator operator;
   operator = Operator.ARITHDIV;
   /*
    * In C the semantics of integer division is "rounding towards zero". In Boogie euclidian division is used. We
    * translate a / b into (a < 0 && a%b != 0) ? ( (b < 0) ? (a/b)+1 : (a/b)-1) : a/b
    */
   if (bothAreIntegerLiterals) {
     final String constantResult = leftValue.divide(rightValue).toString();
     return new IntegerLiteral(loc, constantResult);
   } else {
     final Expression leftSmallerZeroAndThereIsRemainder =
         getLeftSmallerZeroAndThereIsRemainder(loc, exp1, exp2);
     final Expression rightSmallerZero =
         ExpressionFactory.newBinaryExpression(
             loc, BinaryExpression.Operator.COMPLT, exp2, new IntegerLiteral(loc, SFO.NR0));
     final Expression normalDivision =
         ExpressionFactory.newBinaryExpression(loc, operator, exp1, exp2);
     if (exp1 instanceof IntegerLiteral) {
       if (leftValue.signum() == 1) {
         return normalDivision;
       } else if (leftValue.signum() == -1) {
         return ExpressionFactory.newIfThenElseExpression(
             loc,
             rightSmallerZero,
             ExpressionFactory.newBinaryExpression(
                 loc,
                 BinaryExpression.Operator.ARITHMINUS,
                 normalDivision,
                 new IntegerLiteral(loc, SFO.NR1)),
             ExpressionFactory.newBinaryExpression(
                 loc,
                 BinaryExpression.Operator.ARITHPLUS,
                 normalDivision,
                 new IntegerLiteral(loc, SFO.NR1)));
       } else {
         return new IntegerLiteral(loc, SFO.NR0);
       }
     } else if (exp2 instanceof IntegerLiteral) {
       if (rightValue.signum() == 1 || rightValue.signum() == 0) {
         return ExpressionFactory.newIfThenElseExpression(
             loc,
             leftSmallerZeroAndThereIsRemainder,
             ExpressionFactory.newBinaryExpression(
                 loc,
                 BinaryExpression.Operator.ARITHPLUS,
                 normalDivision,
                 new IntegerLiteral(loc, SFO.NR1)),
             normalDivision);
       } else if (rightValue.signum() == -1) {
         return ExpressionFactory.newIfThenElseExpression(
             loc,
             leftSmallerZeroAndThereIsRemainder,
             ExpressionFactory.newBinaryExpression(
                 loc,
                 BinaryExpression.Operator.ARITHMINUS,
                 normalDivision,
                 new IntegerLiteral(loc, SFO.NR1)),
             normalDivision);
       }
       throw new UnsupportedOperationException(
           "Is it expected that this is a fall-through switch?");
     } else {
       return ExpressionFactory.newIfThenElseExpression(
           loc,
           leftSmallerZeroAndThereIsRemainder,
           ExpressionFactory.newIfThenElseExpression(
               loc,
               rightSmallerZero,
               ExpressionFactory.newBinaryExpression(
                   loc,
                   BinaryExpression.Operator.ARITHMINUS,
                   normalDivision,
                   new IntegerLiteral(loc, SFO.NR1)),
               ExpressionFactory.newBinaryExpression(
                   loc,
                   BinaryExpression.Operator.ARITHPLUS,
                   normalDivision,
                   new IntegerLiteral(loc, SFO.NR1))),
           normalDivision);
     }
   }
 }