diff options
author | Damian Gryski <[email protected]> | 2023-06-01 10:41:36 -0700 |
---|---|---|
committer | Ron Evans <[email protected]> | 2023-06-09 17:30:02 +0200 |
commit | f5f4751088bd40a8680899eefeb9854c8dbf4b33 (patch) | |
tree | b7a20ff88c6f31d368fcc783a6a92fa81021ab33 /transform | |
parent | 62fb386d57a0080881c756000e42a2c873372eb8 (diff) | |
download | tinygo-f5f4751088bd40a8680899eefeb9854c8dbf4b33.tar.gz tinygo-f5f4751088bd40a8680899eefeb9854c8dbf4b33.zip |
compiler,transform: fix for pointer-to-pointer type switches from @aykevl
Diffstat (limited to 'transform')
-rw-r--r-- | transform/interface-lowering.go | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/transform/interface-lowering.go b/transform/interface-lowering.go index ebd47ff8f..11d81e4f6 100644 --- a/transform/interface-lowering.go +++ b/transform/interface-lowering.go @@ -285,11 +285,27 @@ func (p *lowerInterfacesPass) run() error { for _, use := range getUses(p.mod.NamedFunction("runtime.typeAssert")) { actualType := use.Operand(0) name := strings.TrimPrefix(use.Operand(1).Name(), "reflect/types.typeid:") + gepOffset := uint64(0) + for strings.HasPrefix(name, "pointer:pointer:") { + // This is a type like **int, which has the name pointer:pointer:int + // but is encoded using pointer tagging. + // Calculate the pointer tag, which is emitted as a GEP instruction. + name = name[len("pointer:"):] + gepOffset++ + } + if t, ok := p.types[name]; ok { // The type exists in the program, so lower to a regular pointer // comparison. p.builder.SetInsertPointBefore(use) - commaOk := p.builder.CreateICmp(llvm.IntEQ, t.typecodeGEP, actualType, "typeassert.ok") + typecodeGEP := t.typecodeGEP + if gepOffset != 0 { + // This is a tagged pointer. + typecodeGEP = llvm.ConstInBoundsGEP(p.ctx.Int8Type(), typecodeGEP, []llvm.Value{ + llvm.ConstInt(p.ctx.Int64Type(), gepOffset, false), + }) + } + commaOk := p.builder.CreateICmp(llvm.IntEQ, typecodeGEP, actualType, "typeassert.ok") use.ReplaceAllUsesWith(commaOk) } else { // The type does not exist in the program, so lower to a constant |