From 0e0588572f3b046127839422e1855607676d5884 Mon Sep 17 00:00:00 2001 From: Marco Manino Date: Tue, 13 Feb 2024 17:48:19 +0100 Subject: [PATCH 1/2] Checking for methodset existance --- interp/interpreter.go | 4 ++++ testdata/init.go | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/interp/interpreter.go b/interp/interpreter.go index 605f4d8fc6..e0074ba26a 100644 --- a/interp/interpreter.go +++ b/interp/interpreter.go @@ -427,6 +427,10 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent if err != nil { return nil, mem, r.errorAt(inst, err) } + if typecodePtr.offset() == 0 { + locals[inst.localIndex] = literalValue{uint8(0)} + break + } typecodePtrOffset, err := typecodePtr.addOffset(-int64(r.pointerSize)) if err != nil { return nil, mem, r.errorAt(inst, err) // unlikely diff --git a/testdata/init.go b/testdata/init.go index fa470fd54f..8b34db3f38 100644 --- a/testdata/init.go +++ b/testdata/init.go @@ -109,3 +109,14 @@ func sliceString(s string, start, end int) string { func sliceSlice(s []int, start, end int) []int { return s[start:end] } + +type outside struct{} + +func init() { + _, _ = any(0).(interface{ DoesNotExist() }) + _, _ = any("").(interface{ DoesNotExist() }) + _, _ = any(outside{}).(interface{ DoesNotExist() }) + + type inside struct{} + _, _ = any(inside{}).(interface{ DoesNotExist() }) +} From a5a92cba4a628f59e2e4d1a9b446199ad86bc574 Mon Sep 17 00:00:00 2001 From: Marco Manino Date: Mon, 18 Mar 2024 08:32:17 +0100 Subject: [PATCH 2/2] Adding a comment --- interp/interpreter.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/interp/interpreter.go b/interp/interpreter.go index e0074ba26a..ea5eeaa12e 100644 --- a/interp/interpreter.go +++ b/interp/interpreter.go @@ -427,13 +427,20 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent if err != nil { return nil, mem, r.errorAt(inst, err) } + // typecodePtr always point to the numMethod field in the type + // description struct. The methodSet, when present, comes right + // before the numMethod field (the compiler doesn't generate + // method sets for concrete types without methods). + // Considering that the compiler doesn't emit interface type + // asserts for interfaces with no methods (as the always succeed) + // then if the offset is zero, this assert must always fail. if typecodePtr.offset() == 0 { locals[inst.localIndex] = literalValue{uint8(0)} break } typecodePtrOffset, err := typecodePtr.addOffset(-int64(r.pointerSize)) if err != nil { - return nil, mem, r.errorAt(inst, err) // unlikely + return nil, mem, r.errorAt(inst, err) } methodSetPtr, err := mem.load(typecodePtrOffset, r.pointerSize).asPointer(r) if err != nil {