]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
fix array creation expressions with side-effects, fixes bug 472984 e086fada22eb7221cdbe34d7d4ac41445a50130a
authorJuerg Billeter <j@bitron.ch>
Mon, 21 Jan 2008 23:08:22 +0000 (23:08 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Mon, 21 Jan 2008 23:08:22 +0000 (23:08 +0000)
2008-01-22  Juerg Billeter  <j@bitron.ch>

* gobject/valaccodearraycreationexpressionbinding.vala,
  gobject/valaccodegenerator.vala: fix array creation expressions with
  side-effects, fixes bug 472984

* tests/arrays.vala: test array creation expressions with side-effects

svn path=/trunk/; revision=878

ChangeLog
gobject/valaccodearraycreationexpressionbinding.vala
gobject/valaccodegenerator.vala
tests/arrays.vala

index bbce2755295bd0cb44ddd930981c7a3123dac3fb..0d6705f6a4817d0c7bea9c02927e2ad3441b5d7c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-01-22  Jürg Billeter  <j@bitron.ch>
+
+       * gobject/valaccodearraycreationexpressionbinding.vala,
+         gobject/valaccodegenerator.vala: fix array creation expressions with
+         side-effects, fixes bug 472984
+
+       * tests/arrays.vala: test array creation expressions with side-effects
+
 2008-01-21  Jürg Billeter  <j@bitron.ch>
 
        * tests/Makefile.am, tests/arrays.exp, tests/arrays.vala: combine array
index 0b41bb006ff386755f15462e9eda3b3c1699e9ae..80f9a605607c9e9c23237f5507620bb1b1aa3fda 100644 (file)
@@ -1,6 +1,6 @@
 /* valaccodearraycreationexpressionbinding.vala
  *
- * Copyright (C) 2006-2007  Jürg Billeter, Raffaele Sandrini
+ * Copyright (C) 2006-2008  Jürg Billeter, Raffaele Sandrini
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -43,12 +43,21 @@ public class Vala.CCodeArrayCreationExpressionBinding : CCodeExpressionBinding {
                bool first = true;
                CCodeExpression cexpr = null;
                foreach (Expression size in expr.get_sizes ()) {
-                       CCodeExpression csize;
+                       CCodeExpression csize = (CCodeExpression) size.ccodenode;
+
+                       if (!codegen.is_pure_ccode_expression (csize)) {
+                               var temp_var = codegen.get_temp_variable_declarator (codegen.int_type, false, expr);
+                               var name_cnode = new CCodeIdentifier (temp_var.name);
+                               size.ccodenode = name_cnode;
+
+                               codegen.temp_vars.insert (0, temp_var);
+
+                               csize = new CCodeParenthesizedExpression (new CCodeAssignment (name_cnode, csize));
+                       }
+
                        if (expr.element_type.data_type != null && expr.element_type.data_type.is_reference_type ()) {
                                // add extra item to have array NULL-terminated for all reference types
-                               csize = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, (CCodeExpression) size.ccodenode, new CCodeConstant ("1"));
-                       } else {
-                               csize = (CCodeExpression) size.ccodenode;
+                               csize = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, csize, new CCodeConstant ("1"));
                        }
 
                        if (first) {
index 71915a327e31fc7a1dece44827c30683c0cffdb0..97dbd1613c556da3bf2ebdbe21113b5765841723 100644 (file)
@@ -496,13 +496,36 @@ public class Vala.CCodeGenerator : CodeGenerator {
        }
 
        private bool is_constant_ccode_expression (CCodeExpression! cexpr) {
-               if (cexpr is CCodeConstant)
+               if (cexpr is CCodeConstant) {
                        return true;
+               } else if (cexpr is CCodeBinaryExpression) {
+                       var cbinary = (CCodeBinaryExpression) cexpr;
+                       return is_constant_ccode_expression (cbinary.left) && is_constant_ccode_expression (cbinary.right);
+               }
 
                var cparenthesized = (cexpr as CCodeParenthesizedExpression);
                return (null != cparenthesized && is_constant_ccode_expression (cparenthesized.inner));
        }
 
+       /**
+        * Returns whether the passed cexpr is a pure expression, i.e. an
+        * expression without side-effects.
+        */
+       public bool is_pure_ccode_expression (CCodeExpression! cexpr) {
+               if (cexpr is CCodeConstant || cexpr is CCodeIdentifier) {
+                       return true;
+               } else if (cexpr is CCodeBinaryExpression) {
+                       var cbinary = (CCodeBinaryExpression) cexpr;
+                       return is_pure_ccode_expression (cbinary.left) && is_constant_ccode_expression (cbinary.right);
+               } else if (cexpr is CCodeMemberAccess) {
+                       var cma = (CCodeMemberAccess) cexpr;
+                       return is_pure_ccode_expression (cma.inner);
+               }
+
+               var cparenthesized = (cexpr as CCodeParenthesizedExpression);
+               return (null != cparenthesized && is_pure_ccode_expression (cparenthesized.inner));
+       }
+
        public override void visit_formal_parameter (FormalParameter! p) {
                p.accept_children (this);
 
index ce5f715f6fd98e2ff0947cb863cbb891c0e4af5f..3847dc7599b8eee6b6fa0ca7e22c966b0716b3d6 100644 (file)
@@ -20,7 +20,8 @@ class Maman.Foo : Object {
                a[3] = 4;
                
                stdout.printf (" 4");
-               
+
+               int i = 0;
                if (a[0] == 1) {
                        stdout.printf (" 5");
                }
@@ -124,18 +125,7 @@ class Maman.Foo : Object {
                stdout.printf ("\n");
        }
 
-       static void main (string[] args) {
-               test_integer_array ();
-               test_string_array ();
-               test_object_array ();
-
-               stdout.printf ("Array Test: 1");
-               
-               var bar = new Bar ();
-               bar.run ();
-
-               stdout.printf (" 5\n");
-
+       static void test_switch_on_strings () {
                var tokens = new string[] { "Hello", "World", "this", "is", "Vala", "GNOME", null };
                var t4 = " 5";
 
@@ -175,6 +165,30 @@ class Maman.Foo : Object {
 
                stdout.printf ("\n");
        }
+
+       static void test_array_creation_side_effects () {
+               int i = 5;
+               var arr = new int[i++];
+               assert (arr.length == 5);
+               assert (i == 6);
+       }
+
+       static void main (string[] args) {
+               test_integer_array ();
+               test_string_array ();
+               test_object_array ();
+
+               stdout.printf ("Array Test: 1");
+               
+               var bar = new Bar ();
+               bar.run ();
+
+               stdout.printf (" 5\n");
+
+               test_switch_on_strings ();
+
+               test_array_creation_side_effects ();
+       }
 }
 
 class Maman.Bar : Object {