diff options
author | monojenkins <jo.shields+jenkins@xamarin.com> | 2020-02-03 14:08:15 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-03 14:08:15 +0300 |
commit | 9ea350ed3c963c77f0f4f77ec590cc3c84773424 (patch) | |
tree | c36d97ff1a7d852be4872af6e0f811835136515c | |
parent | 20a641e4a091eec56e6d5ad8db608ff85f3ef29f (diff) |
[interp] Fix enum constrained calls on netcore (#18659)
We were failing to dereference a managed pointer to the enum, due to incorrect checks, when doing a constrained call.
Fixes https://github.com/mono/mono/issues/18530
Co-authored-by: Vlad Brezae <brezaevlad@gmail.com>
-rw-r--r-- | mono/mini/interp/transform.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/mono/mini/interp/transform.c b/mono/mini/interp/transform.c index ad7154ef66b..be002146491 100644 --- a/mono/mini/interp/transform.c +++ b/mono/mini/interp/transform.c @@ -2193,8 +2193,14 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target interp_add_ins (td, MINT_LDIND_I); td->last_ins->data [0] = csignature->param_count; } else if (target_method->klass == mono_defaults.object_class || target_method->klass == m_class_get_parent (mono_defaults.enum_class) || target_method->klass == mono_defaults.enum_class) { - if (target_method->klass == mono_defaults.enum_class && (td->sp - csignature->param_count - 1)->type == STACK_TYPE_MP) { - /* managed pointer on the stack, we need to deref that puppy */ + /* + * Constrained expects a managed pointer that normally needs dereferencing. + * For value types that have their storage on the vtstack, a managed pointer + * to it is identical to the internal pointer that is passed on the stack + * when using the value type, not needing any dereferencing. + */ + g_assert ((td->sp - csignature->param_count - 1)->type == STACK_TYPE_MP); + if (mint_type (m_class_get_byval_arg (constrained_class)) != MINT_TYPE_VT) { /* Always load the entire stackval, to handle also the case where the enum has long storage */ interp_add_ins (td, MINT_LDIND_I8); td->last_ins->data [0] = csignature->param_count; @@ -2209,7 +2215,8 @@ interp_transform_call (TransformData *td, MonoMethod *method, MonoMethod *target * but that type doesn't override the method we're * calling, so we need to box `this'. */ - if (target_method->klass == mono_defaults.enum_class && (td->sp - csignature->param_count - 1)->type == STACK_TYPE_MP) { + g_assert ((td->sp - csignature->param_count - 1)->type == STACK_TYPE_MP); + if (mint_type (m_class_get_byval_arg (constrained_class)) != MINT_TYPE_VT) { /* managed pointer on the stack, we need to deref that puppy */ /* Always load the entire stackval, to handle also the case where the enum has long storage */ interp_add_ins (td, MINT_LDIND_I8); |