From 3697849067609aba70939497a469d2ab13fe48f4 Mon Sep 17 00:00:00 2001 From: mappu Date: Sat, 18 Jan 2025 17:57:16 +1300 Subject: [PATCH] genbindings: use dynamic_cast's return value to verify override is safe --- cmd/genbindings/emitcabi.go | 12 +++++++++--- cmd/genbindings/emitgo.go | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/cmd/genbindings/emitcabi.go b/cmd/genbindings/emitcabi.go index 32f84bae..0e2f93f3 100644 --- a/cmd/genbindings/emitcabi.go +++ b/cmd/genbindings/emitcabi.go @@ -749,7 +749,7 @@ extern "C" { } for _, m := range c.VirtualMethods() { - ret.WriteString(fmt.Sprintf("void %s_override_virtual_%s(%s* self, intptr_t slot);\n", methodPrefixName, m.SafeMethodName(), "void" /*methodPrefixName*/)) + ret.WriteString(fmt.Sprintf("bool %s_override_virtual_%s(%s* self, intptr_t slot);\n", methodPrefixName, m.SafeMethodName(), "void" /*methodPrefixName*/)) ret.WriteString(fmt.Sprintf("%s %s_virtualbase_%s(%s);\n", m.ReturnType.RenderTypeCabi(), methodPrefixName, m.SafeMethodName(), emitParametersCabi(m, ifv(m.IsConst, "const ", "")+"void" /*methodPrefixName*/ +"*"))) } @@ -1178,8 +1178,14 @@ extern "C" { // upclass it ret.WriteString( - `void ` + methodPrefixName + `_override_virtual_` + m.SafeMethodName() + `(void* self, intptr_t slot) {` + "\n" + - "\tdynamic_cast<" + cppClassName + "*>( (" + cabiClassName(c.ClassName) + "*)(self) )->handle__" + m.SafeMethodName() + " = slot;\n" + + `bool ` + methodPrefixName + `_override_virtual_` + m.SafeMethodName() + `(void* self, intptr_t slot) {` + "\n" + + "\t" + cppClassName + "* self_cast = dynamic_cast<" + cppClassName + "*>( (" + cabiClassName(c.ClassName) + "*)(self) );\n" + + "\tif (self_cast == nullptr) {\n" + + "\t\treturn false;\n" + + "\t}\n" + + "\t\n" + + "\tself_cast->handle__" + m.SafeMethodName() + " = slot;\n" + + "\treturn true;\n" + "}\n" + "\n", ) diff --git a/cmd/genbindings/emitgo.go b/cmd/genbindings/emitgo.go index cb5a6774..5f337092 100644 --- a/cmd/genbindings/emitgo.go +++ b/cmd/genbindings/emitgo.go @@ -1035,10 +1035,10 @@ import "C" goCbType += `) ` + m.ReturnType.renderReturnTypeGo(&gfs) callbackName := cabiCallbackName(c, m) ret.WriteString(`func (this *` + goClassName + `) On` + m.SafeMethodName() + `(slot ` + goCbType + `) { - if ! this.isSubclass { + ok := C.` + goClassName + `_override_virtual_` + m.SafeMethodName() + `(unsafe.Pointer(this.h), C.intptr_t(cgo.NewHandle(slot)) ) + if !ok { panic("miqt: can only override virtual methods for directly constructed types") } - C.` + goClassName + `_override_virtual_` + m.SafeMethodName() + `(unsafe.Pointer(this.h), C.intptr_t(cgo.NewHandle(slot)) ) } //export ` + callbackName + `