diff options
| author | Andrew Waterman | 2019-04-12 17:51:04 -0700 |
|---|---|---|
| committer | edwardcwang | 2019-04-15 13:07:11 -0700 |
| commit | a4a29e29c3f1eed18f851dcf10bdc845571dfcb6 (patch) | |
| tree | 876999a0301d4ef86e8bb0712e8bc3ec3d2f9ef7 /chiselFrontend | |
| parent | 0028c64922a85087b2b6a6062fe202294e70855a (diff) | |
Avoid silently truncating BigInt to Int
- Introduce internal helper `castToInt`, which issues an error when the input
BigInt can't be represented as Int.
- Use `castToInt` wherever we were using `toInt` in a potentially unsafe way.
Diffstat (limited to 'chiselFrontend')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/Bits.scala | 16 | ||||
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 9 |
2 files changed, 17 insertions, 8 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index 43a851ed..e35d12f0 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -162,7 +162,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi // This preserves old behavior while a more more consistent API is under debate // See https://github.com/freechipsproject/chisel3/issues/867 litOption.map { value => - (((value >> x.toInt) & 1) == 1).asBool + (((value >> castToInt(x, "Index")) & 1) == 1).asBool }.getOrElse { requireIsHardware(this, "bits to be indexed") pushOp(DefPrim(sourceInfo, Bool(), BitsExtractOp, this.ref, ILit(x), ILit(x))) @@ -238,7 +238,7 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi /** @group SourceInfoTransformMacro */ final def do_apply(x: BigInt, y: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - apply(x.toInt, y.toInt) + apply(castToInt(x, "High index"), castToInt(y, "Low index")) private[core] def unop[T <: Data](sourceInfo: SourceInfo, dest: T, op: PrimOp): T = { requireIsHardware(this, "bits operated on") @@ -866,13 +866,13 @@ sealed class UInt private[core] (width: Width) extends Bits(width) with Num[UInt override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width + that), ShiftLeftOp, validateShiftAmount(that)) override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - this << that.toInt + this << castToInt(that, "Shift amount") override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width.dynamicShiftLeft(that.width)), DynamicShiftLeftOp, that) override def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width.shiftRight(that)), ShiftRightOp, validateShiftAmount(that)) override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = - this >> that.toInt + this >> castToInt(that, "Shift amount") override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = binop(sourceInfo, UInt(this.width), DynamicShiftRightOp, that) @@ -1155,13 +1155,13 @@ sealed class SInt private[core] (width: Width) extends Bits(width) with Num[SInt override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width + that), ShiftLeftOp, validateShiftAmount(that)) override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = - this << that.toInt + this << castToInt(that, "Shift amount") override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width.dynamicShiftLeft(that.width)), DynamicShiftLeftOp, that) override def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width.shiftRight(that)), ShiftRightOp, validateShiftAmount(that)) override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = - this >> that.toInt + this >> castToInt(that, "Shift amount") override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): SInt = binop(sourceInfo, SInt(this.width), DynamicShiftRightOp, that) @@ -1602,13 +1602,13 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint) override def do_<< (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width + that, this.binaryPoint), ShiftLeftOp, validateShiftAmount(that)) override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = - (this << that.toInt).asFixedPoint(this.binaryPoint) + (this << castToInt(that, "Shift amount")).asFixedPoint(this.binaryPoint) override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width.dynamicShiftLeft(that.width), this.binaryPoint), DynamicShiftLeftOp, that) override def do_>> (that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width.shiftRight(that), this.binaryPoint), ShiftRightOp, validateShiftAmount(that)) override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = - (this >> that.toInt).asFixedPoint(this.binaryPoint) + (this >> castToInt(that, "Shift amount")).asFixedPoint(this.binaryPoint) override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): FixedPoint = binop(sourceInfo, FixedPoint(this.width, this.binaryPoint), DynamicShiftRightOp, that) diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 4105a699..1163171c 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -378,3 +378,12 @@ object DynamicNamingStack { prefixRef } } + +/** Casts BigInt to Int, issuing an error when the input isn't representable. */ +private[chisel3] object castToInt { + def apply(x: BigInt, msg: String): Int = { + val res = x.toInt + require(x == res, s"$msg $x is too large to be represented as Int") + res + } +} |
