diff --git a/gnovm/pkg/gnolang/op_assign.go b/gnovm/pkg/gnolang/op_assign.go index 5e841fb18fd..b42bb4744c0 100644 --- a/gnovm/pkg/gnolang/op_assign.go +++ b/gnovm/pkg/gnolang/op_assign.go @@ -20,6 +20,9 @@ func (m *Machine) doOpDefine() { } } } + if !m.PreprocessorMode && isUntyped(rvs[i].T) && rvs[i].T.Kind() != BoolKind { + panic("untyped conversion should not happen at runtime") + } ptr.Assign2(m.Alloc, m.Store, m.Realm, rvs[i], true) } } @@ -41,6 +44,9 @@ func (m *Machine) doOpAssign() { } } } + if !m.PreprocessorMode && isUntyped(rvs[i].T) && rvs[i].T.Kind() != BoolKind { + panic("untyped conversion should not happen at runtime") + } lv.Assign2(m.Alloc, m.Store, m.Realm, rvs[i], true) } } diff --git a/gnovm/pkg/gnolang/op_decl.go b/gnovm/pkg/gnolang/op_decl.go index c9c04ccf76d..6dbae2d3edf 100644 --- a/gnovm/pkg/gnolang/op_decl.go +++ b/gnovm/pkg/gnolang/op_decl.go @@ -29,35 +29,31 @@ func (m *Machine) doOpValueDecl() { } else { tv = rvs[i] } - if nt != nil { - if nt.Kind() == InterfaceKind { - if isUntyped(tv.T) { - ConvertUntypedTo(&tv, nil) - } else { - // keep type as is. + + if isUntyped(tv.T) { + if !s.Const { + if !m.PreprocessorMode && rvs[i].T.Kind() != BoolKind { + panic("untyped conversion should not happen at runtime") } - } else { - if isUntyped(tv.T) { - ConvertUntypedTo(&tv, nt) - } else { - if debug { - if nt.TypeID() != tv.T.TypeID() && - baseOf(nt).TypeID() != tv.T.TypeID() { - panic(fmt.Sprintf( - "type mismatch: %s vs %s", - nt.TypeID(), - tv.T.TypeID(), - )) - } + ConvertUntypedTo(&tv, nil) + } + } else if nt != nil { + // if nt.T is an interface, maintain tv.T as-is. + if nt.Kind() != InterfaceKind { + if debug { + if nt.TypeID() != tv.T.TypeID() && + baseOf(nt).TypeID() != tv.T.TypeID() { + panic(fmt.Sprintf( + "type mismatch: %s vs %s", + nt.TypeID(), + tv.T.TypeID(), + )) } - tv.T = nt } + tv.T = nt } - } else if s.Const { - // leave untyped as is. - } else if isUntyped(tv.T) { - ConvertUntypedTo(&tv, nil) } + nx := &s.NameExprs[i] ptr := lb.GetPointerToMaybeHeapDefine(m.Store, nx) ptr.Assign2(m.Alloc, m.Store, m.Realm, tv, false) diff --git a/gnovm/pkg/gnolang/uverse.go b/gnovm/pkg/gnolang/uverse.go index 55791ba4900..074f7a51b66 100644 --- a/gnovm/pkg/gnolang/uverse.go +++ b/gnovm/pkg/gnolang/uverse.go @@ -1050,6 +1050,9 @@ func makeUverseNode() { } } + if isUntyped(exception.Value.T) { + ConvertUntypedTo(&exception.Value, nil) + } m.PushValue(exception.Value) // Recover complete; remove exceptions. m.Exceptions = nil diff --git a/gnovm/pkg/gnolang/values_conversions.go b/gnovm/pkg/gnolang/values_conversions.go index 920ed655ec9..ce256680de6 100644 --- a/gnovm/pkg/gnolang/values_conversions.go +++ b/gnovm/pkg/gnolang/values_conversions.go @@ -1316,28 +1316,14 @@ func ConvertUntypedTo(tv *TypedValue, t Type) { } switch tv.T { case UntypedBoolType: - if debug { - if t.Kind() != BoolKind { - panic("untyped bool can only be converted to bool kind") - } - } tv.T = t case UntypedRuneType: ConvertUntypedRuneTo(tv, t) case UntypedBigintType: - if preprocessing.Load() == 0 { - panic("untyped Bigint conversion should not happen during interpretation") - } ConvertUntypedBigintTo(tv, tv.V.(BigintValue), t) case UntypedBigdecType: - if preprocessing.Load() == 0 { - panic("untyped Bigdec conversion should not happen during interpretation") - } ConvertUntypedBigdecTo(tv, tv.V.(BigdecValue), t) case UntypedStringType: - if preprocessing.Load() == 0 { - panic("untyped String conversion should not happen during interpretation") - } if t.Kind() == StringKind { tv.T = t return