[vala] GAsync: Fix temporary variable initialization in loops
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] GAsync: Fix temporary variable initialization in loops
- Date: Wed, 28 Oct 2009 15:11:47 +0000 (UTC)
commit 3eba8bfcff9f42e5971bc31980d9f317d1782a88
Author: Jürg Billeter <j bitron ch>
Date: Wed Oct 28 16:10:29 2009 +0100
GAsync: Fix temporary variable initialization in loops
Fixes bug 599568.
codegen/valaccodebasemodule.vala | 81 +++++++++++++++++++++---------------
tests/Makefile.am | 1 +
tests/asynchronous/bug599568.vala | 9 ++++
3 files changed, 57 insertions(+), 34 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 4da1f21..84c066f 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2718,44 +2718,57 @@ internal class Vala.CCodeBaseModule : CCodeModule {
public void append_temp_decl (CCodeFragment cfrag, List<LocalVariable> temp_vars) {
foreach (LocalVariable local in temp_vars) {
+ var cdecl = new CCodeDeclaration (local.variable_type.get_cname ());
+
+ var vardecl = new CCodeVariableDeclarator (local.name, null, local.variable_type.get_cdeclarator_suffix ());
+ // sets #line
+ local.ccodenode = vardecl;
+ cdecl.add_declarator (vardecl);
+
+ var st = local.variable_type.data_type as Struct;
+ var array_type = local.variable_type as ArrayType;
+
+ if (local.name.has_prefix ("*")) {
+ // do not dereference unintialized variable
+ // initialization is not needed for these special
+ // pointer temp variables
+ // used to avoid side-effects in assignments
+ } else if (local.no_init) {
+ // no initialization necessary for this temp var
+ } else if (!local.variable_type.nullable &&
+ (st != null && !st.is_simple_type ()) ||
+ (array_type != null && array_type.fixed_length)) {
+ // 0-initialize struct with struct initializer { 0 }
+ // necessary as they will be passed by reference
+ var clist = new CCodeInitializerList ();
+ clist.append (new CCodeConstant ("0"));
+
+ vardecl.initializer = clist;
+ vardecl.init0 = true;
+ } else if (local.variable_type.is_reference_type_or_type_parameter () ||
+ local.variable_type.nullable) {
+ vardecl.initializer = new CCodeConstant ("NULL");
+ vardecl.init0 = true;
+ }
+
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (local.variable_type.get_cname (), local.name);
- // no initialization necessary, closure struct is zeroed
- } else {
- var cdecl = new CCodeDeclaration (local.variable_type.get_cname ());
-
- var vardecl = new CCodeVariableDeclarator (local.name, null, local.variable_type.get_cdeclarator_suffix ());
- // sets #line
- local.ccodenode = vardecl;
- cdecl.add_declarator (vardecl);
-
- var st = local.variable_type.data_type as Struct;
- var array_type = local.variable_type as ArrayType;
-
- if (local.name.has_prefix ("*")) {
- // do not dereference unintialized variable
- // initialization is not needed for these special
- // pointer temp variables
- // used to avoid side-effects in assignments
- } else if (local.no_init) {
- // no initialization necessary for this temp var
- } else if (!local.variable_type.nullable &&
- (st != null && !st.is_simple_type ()) ||
- (array_type != null && array_type.fixed_length)) {
- // 0-initialize struct with struct initializer { 0 }
- // necessary as they will be passed by reference
- var clist = new CCodeInitializerList ();
- clist.append (new CCodeConstant ("0"));
-
- vardecl.initializer = clist;
- vardecl.init0 = true;
- } else if (local.variable_type.is_reference_type_or_type_parameter () ||
- local.variable_type.nullable) {
- vardecl.initializer = new CCodeConstant ("NULL");
- vardecl.init0 = true;
+ // even though closure struct is zerod, we need to initialize temporary variables
+ // as they might be used multiple times when declared in a loop
+
+ if (vardecl.initializer is CCodeInitializerList) {
+ // C does not support initializer lists in assignments, use memset instead
+ source_declarations.add_include ("string.h");
+ var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+ memset_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (local.name)));
+ memset_call.add_argument (new CCodeConstant ("0"));
+ memset_call.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (local.variable_type.get_cname ())));
+ cfrag.append (new CCodeExpressionStatement (memset_call));
+ } else if (vardecl.initializer != null) {
+ cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (local.name), vardecl.initializer)));
}
-
+ } else {
cfrag.append (cdecl);
}
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index fa289a3..4773f3a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -69,6 +69,7 @@ TESTS = \
asynchronous/bug598677.vala \
asynchronous/bug598697.vala \
asynchronous/bug598698.vala \
+ asynchronous/bug599568.vala \
dbus/basic-types.test \
dbus/arrays.test \
dbus/async.test \
diff --git a/tests/asynchronous/bug599568.vala b/tests/asynchronous/bug599568.vala
new file mode 100644
index 0000000..77a66fd
--- /dev/null
+++ b/tests/asynchronous/bug599568.vala
@@ -0,0 +1,9 @@
+async void do_foo () {
+ for (int i = 0; i < 2; i++) {
+ Value value = 42;
+ }
+}
+
+void main () {
+ do_foo ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]