From e086fada22eb7221cdbe34d7d4ac41445a50130a Mon Sep 17 00:00:00 2001 From: Juerg Billeter Date: Mon, 21 Jan 2008 23:08:22 +0000 Subject: [PATCH] fix array creation expressions with side-effects, fixes bug 472984 2008-01-22 Juerg Billeter * 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 | 8 ++++ ...laccodearraycreationexpressionbinding.vala | 19 ++++++--- gobject/valaccodegenerator.vala | 25 +++++++++++- tests/arrays.vala | 40 +++++++++++++------ 4 files changed, 73 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index bbce27552..0d6705f6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-01-22 Jürg Billeter + + * 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 * tests/Makefile.am, tests/arrays.exp, tests/arrays.vala: combine array diff --git a/gobject/valaccodearraycreationexpressionbinding.vala b/gobject/valaccodearraycreationexpressionbinding.vala index 0b41bb006..80f9a6056 100644 --- a/gobject/valaccodearraycreationexpressionbinding.vala +++ b/gobject/valaccodearraycreationexpressionbinding.vala @@ -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) { diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index 71915a327..97dbd1613 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -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); diff --git a/tests/arrays.vala b/tests/arrays.vala index ce5f715f6..3847dc759 100644 --- a/tests/arrays.vala +++ b/tests/arrays.vala @@ -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 { -- 2.47.2