aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler/channel.go
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2020-03-10 21:58:34 +0100
committerRon Evans <[email protected]>2020-03-13 16:15:36 -0700
commit79dae62c781bc3fe6df76d5a609f62fcc7a43310 (patch)
tree5c660c32a9897d7de7c24e69f1b74516f41ee545 /compiler/channel.go
parent1a7369af6e3abc7f95f867d42ed037a3ebea9c0f (diff)
downloadtinygo-79dae62c781bc3fe6df76d5a609f62fcc7a43310.tar.gz
tinygo-79dae62c781bc3fe6df76d5a609f62fcc7a43310.zip
compiler,runtime: check for channel size limits
This patch is a combination of two related changes: 1. The compiler now allows other types than `int` when specifying the size of a channel in a make(chan ..., size) call. 2. The compiler now checks for maximum allowed channel sizes. Such checks are trivially optimized out in the vast majority of cases as channel sizes are usually constant. I discovered this issue when trying out channels on AVR.
Diffstat (limited to 'compiler/channel.go')
-rw-r--r--compiler/channel.go6
1 files changed, 6 insertions, 0 deletions
diff --git a/compiler/channel.go b/compiler/channel.go
index ac16510c6..de7b12e29 100644
--- a/compiler/channel.go
+++ b/compiler/channel.go
@@ -15,6 +15,12 @@ func (c *Compiler) emitMakeChan(frame *Frame, expr *ssa.MakeChan) llvm.Value {
elementSize := c.targetData.TypeAllocSize(c.getLLVMType(expr.Type().(*types.Chan).Elem()))
elementSizeValue := llvm.ConstInt(c.uintptrType, elementSize, false)
bufSize := c.getValue(frame, expr.Size)
+ c.emitChanBoundsCheck(frame, elementSize, bufSize, expr.Size.Type().Underlying().(*types.Basic), expr.Pos())
+ if bufSize.Type().IntTypeWidth() < c.uintptrType.IntTypeWidth() {
+ bufSize = c.builder.CreateZExt(bufSize, c.uintptrType, "")
+ } else if bufSize.Type().IntTypeWidth() > c.uintptrType.IntTypeWidth() {
+ bufSize = c.builder.CreateTrunc(bufSize, c.uintptrType, "")
+ }
return c.createRuntimeCall("chanMake", []llvm.Value{elementSizeValue, bufSize}, "")
}