[sgen] Fix the merging code.
authorRodrigo Kumpera <kumpera@gmail.com>
Wed, 12 Mar 2014 21:30:07 +0000 (17:30 -0400)
committerRodrigo Kumpera <kumpera@gmail.com>
Thu, 13 Mar 2014 22:19:22 +0000 (18:19 -0400)
commitd8f724157b5a065d12ec4f8657e87006a0f8bde8
tree8dde3bf89aed07516a631b3b33517803d7a94dc6
parent89d46b1b36a4002b9deb18b2b4aa1122a3d7722a
[sgen] Fix the merging code.

The right behavior is that the loop move values up to the original size
and them the store after the loop store past it.

Let's see the last 2 iterations:

//i == size - 1 (value = array[size - 2], tmp = array [size - 1])
dyn_array_int_set (array, size, value); //ok
value = tmp; //ok
tmp = dyn_array_int_get (array, i + 1); //tmp has an unknown value, as the last element was never stored to.

//i == size (value = array[size - 1], tmp = array [size])
dyn_array_int_set (array, size, value); //This sets the last element to the right value
value = tmp; //value is undefined, as tmp has
tmp = dyn_array_int_get (array, i + 1); //this is an out-of-bounds read as we're reading 2 elements past the end.

The after the loop store (tmp = array [size + 1]):
dyn_array_int_set (array, size + 1, tmp); //This sets the last element to an unknown value.

With the fix on the last iteration is - 1. The post store will use value, which has
the right value (array [size - 1]).
mono/metadata/sgen-bridge.c