]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Fix array move when the areas don't overlap
authorMaciej Piechotka <uzytkownik2@gmail.com>
Sat, 7 Jan 2012 03:19:25 +0000 (04:19 +0100)
committerJürg Billeter <j@bitron.ch>
Thu, 12 Jul 2012 12:01:04 +0000 (14:01 +0200)
Fixes bug 667452.

codegen/valaccodearraymodule.vala

index 8e1d09c72385231db333ae758816090b0267e637..c99d474d52e55066594acebc067ece756da7f901 100644 (file)
@@ -338,10 +338,12 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                var element_size = new CCodeIdentifier ("element_size");
                var length = new CCodeIdentifier ("length");
                var src = new CCodeIdentifier ("src");
+               var src_end = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, src, length);
                var dest = new CCodeIdentifier ("dest");
+               var dest_end = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, dest, length);
                var src_address = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, src, element_size));
                var dest_address = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, dest, element_size));
-               var dest_end_address = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, dest, length), element_size));
+               var dest_end_address = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, dest_end, element_size));
 
                var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_memmove"));
                ccall.add_argument (dest_address);
@@ -349,7 +351,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                ccall.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, length, element_size));
                ccode.add_expression (ccall);
 
-               ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, src, dest));
+               ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.AND, new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, src, dest), new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, src_end, dest)));
 
                var czero1 = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
                czero1.add_argument (src_address);
@@ -357,7 +359,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                czero1.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, dest, src), element_size));
                ccode.add_expression (czero1);
 
-               ccode.add_else ();
+               ccode.else_if (new CCodeBinaryExpression (CCodeBinaryOperator.AND, new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, src, dest), new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, src, dest_end)));
 
                var czero2 = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
                czero2.add_argument (dest_end_address);
@@ -365,6 +367,14 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                czero2.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, src, dest), element_size));
                ccode.add_expression (czero2);
 
+               ccode.else_if (new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, src, dest));
+
+               var czero3 = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+               czero3.add_argument (src_address);
+               czero3.add_argument (new CCodeConstant ("0"));
+               czero3.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, length, element_size));
+               ccode.add_expression (czero3);
+
                ccode.close ();
 
                pop_function ();