Don't throw NRE when len == 0 in Buffer.Memmove (mono/mono#18004)
authorEgor Bogatov <egorbo@gmail.com>
Tue, 3 Dec 2019 14:21:41 +0000 (17:21 +0300)
committerBernhard Urban-Forster <lewurm@gmail.com>
Tue, 3 Dec 2019 14:21:41 +0000 (15:21 +0100)
Commit migrated from https://github.com/mono/mono/commit/8150a38dae6fbf60a8a5ffc20a1d07b911fbc31b

src/mono/mono/mini/intrinsics.c

index 2737b7f..b3de056 100644 (file)
@@ -295,6 +295,13 @@ llvm_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
 
        if (in_corlib && !strcmp (m_class_get_name (cmethod->klass), "Buffer")) {
                if (!strcmp (cmethod->name, "Memmove") && fsig->param_count == 3 && fsig->params [0]->type == MONO_TYPE_PTR && fsig->params [1]->type == MONO_TYPE_PTR) {
+                       MonoBasicBlock *end_bb;
+                       NEW_BBLOCK (cfg, end_bb);
+
+                       // do nothing if len == 0 (even if src or dst are nulls)
+                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [2]->dreg, 0);
+                       MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBEQ, end_bb);
+
                        // throw NRE if src or dst are nulls
                        MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, args [0]->dreg, 0);
                        MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException");
@@ -306,6 +313,7 @@ llvm_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                        ins->sreg2 = args [1]->dreg; // i1* src
                        ins->sreg3 = args [2]->dreg; // i32/i64 len
                        MONO_ADD_INS (cfg->cbb, ins);
+                       MONO_START_BB (cfg, end_bb);
                }
        }