Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormonojenkins <jo.shields+jenkins@xamarin.com>2020-02-03 14:08:15 +0300
committerGitHub <noreply@github.com>2020-02-03 14:08:15 +0300
commit9ea350ed3c963c77f0f4f77ec590cc3c84773424 (patch)
treec36d97ff1a7d852be4872af6e0f811835136515c
parent20a641e4a091eec56e6d5ad8db608ff85f3ef29f (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.c13
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);