aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2022-07-28 14:14:23 +0200
committerRon Evans <[email protected]>2022-07-28 15:43:51 +0200
commit7b1e5f6f99ac1cc9498e67738dcc421471391117 (patch)
tree2ed8063517d6c095cf583d81d6785807c362663c
parent70c52ef1b47fd6b0ed68e322cfcbbf3fd7005315 (diff)
downloadtinygo-7b1e5f6f99ac1cc9498e67738dcc421471391117.tar.gz
tinygo-7b1e5f6f99ac1cc9498e67738dcc421471391117.zip
compiler: implement unsafe.Alignof and unsafe.Sizeof for generic codev0.25.0-beta1
For some reason, these aren't lowered when a generic function is instantiated by the SSA package. I've left unsafe.Offsetof to be implemented later, it's a bit difficult to do correctly the way the code is currently structured.
-rw-r--r--compiler/compiler.go14
-rw-r--r--compiler/testdata/generics.go6
-rw-r--r--compiler/testdata/generics.ll6
3 files changed, 26 insertions, 0 deletions
diff --git a/compiler/compiler.go b/compiler/compiler.go
index 571ae710b..1b588d9c9 100644
--- a/compiler/compiler.go
+++ b/compiler/compiler.go
@@ -1585,6 +1585,20 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
ptr := argValues[0]
len := argValues[1]
return b.CreateGEP(ptr, []llvm.Value{len}, ""), nil
+ case "Alignof": // unsafe.Alignof
+ align := b.targetData.ABITypeAlignment(argValues[0].Type())
+ return llvm.ConstInt(b.uintptrType, uint64(align), false), nil
+ case "Offsetof": // unsafe.Offsetof
+ // This builtin is a bit harder to implement and may need a bit of
+ // refactoring to work (it may be easier to implement if we have access
+ // to the underlying Go SSA instruction). It is also rarely used: it
+ // only applies in generic code and unsafe.Offsetof isn't very commonly
+ // used anyway.
+ // In other words, postpone it to some other day.
+ return llvm.Value{}, b.makeError(pos, "todo: unsafe.Offsetof")
+ case "Sizeof": // unsafe.Sizeof
+ size := b.targetData.TypeAllocSize(argValues[0].Type())
+ return llvm.ConstInt(b.uintptrType, size, false), nil
case "Slice": // unsafe.Slice
// This creates a slice from a pointer and a length.
// Note that the exception mentioned in the documentation (if the
diff --git a/compiler/testdata/generics.go b/compiler/testdata/generics.go
index 439de0ead..fc35538fe 100644
--- a/compiler/testdata/generics.go
+++ b/compiler/testdata/generics.go
@@ -1,5 +1,7 @@
package main
+import "unsafe"
+
type Coord interface {
int | float32
}
@@ -9,6 +11,8 @@ type Point[T Coord] struct {
}
func Add[T Coord](a, b Point[T]) Point[T] {
+ checkSize(unsafe.Alignof(a))
+ checkSize(unsafe.Sizeof(a))
return Point[T]{
X: a.X + b.X,
Y: a.Y + b.Y,
@@ -22,3 +26,5 @@ func main() {
var ai, bi Point[int]
Add(ai, bi)
}
+
+func checkSize(uintptr)
diff --git a/compiler/testdata/generics.ll b/compiler/testdata/generics.ll
index f861cb656..4aa304b07 100644
--- a/compiler/testdata/generics.ll
+++ b/compiler/testdata/generics.ll
@@ -94,6 +94,8 @@ entry:
store float %b.X, float* %b.repack14, align 8
%b.repack15 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %b, i32 0, i32 1
store float %b.Y, float* %b.repack15, align 4
+ call void @main.checkSize(i32 4, i8* undef) #2
+ call void @main.checkSize(i32 8, i8* undef) #2
%complit.repack = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %complit, i32 0, i32 0
store float 0.000000e+00, float* %complit.repack, align 8
%complit.repack17 = getelementptr inbounds %"main.Point[float32]", %"main.Point[float32]"* %complit, i32 0, i32 1
@@ -157,6 +159,8 @@ store.throw7: ; preds = %store.next
unreachable
}
+declare void @main.checkSize(i32, i8*) #0
+
declare void @runtime.nilPanic(i8*) #0
; Function Attrs: nounwind
@@ -185,6 +189,8 @@ entry:
store i32 %b.X, i32* %b.repack14, align 8
%b.repack15 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %b, i32 0, i32 1
store i32 %b.Y, i32* %b.repack15, align 4
+ call void @main.checkSize(i32 4, i8* undef) #2
+ call void @main.checkSize(i32 8, i8* undef) #2
%complit.repack = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %complit, i32 0, i32 0
store i32 0, i32* %complit.repack, align 8
%complit.repack17 = getelementptr inbounds %"main.Point[int]", %"main.Point[int]"* %complit, i32 0, i32 1