+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
/* 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
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) {
}
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);
a[3] = 4;
stdout.printf (" 4");
-
+
+ int i = 0;
if (a[0] == 1) {
stdout.printf (" 5");
}
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";
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 {