}
}
+ public void append_out_param_free (Method? m) {
+ if (m == null) {
+ return;
+ }
+ foreach (Parameter param in m.get_parameters ()) {
+ if (param.direction == ParameterDirection.OUT && param.variable_type.is_disposable ()) {
+ ccode.add_expression (destroy_parameter (param));
+ }
+ }
+ }
+
public bool variable_accessible_in_finally (LocalVariable local) {
if (current_try == null) {
return false;
set_error.add_argument (error_expr);
ccode.add_expression (set_error);
+ // free local variables
append_local_free (current_symbol);
+ // free possibly already assigned out-parameter
+ append_out_param_free (current_method);
+
// We already returned the error above, we must not return anything else here.
var unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
unref.add_argument (async_result_expr);
// free local variables
append_local_free (current_symbol);
+ // free possibly already assigned out-parameter
+ append_out_param_free (current_method);
+
if (current_method is CreationMethod && current_method.parent_symbol is Class) {
var cl = (Class) current_method.parent_symbol;
ccode.add_expression (destroy_value (new GLibValue (new ObjectType (cl), new CCodeIdentifier ("self"), true)));
append_local_free (current_symbol);
}
+ // free possibly already assigned out-parameter
+ append_out_param_free (current_method);
+
var ccritical = new CCodeFunctionCall (new CCodeIdentifier ("g_critical"));
ccritical.add_argument (new CCodeConstant (unexpected ? "\"file %s: line %d: unexpected error: %s (%s, %d)\"" : "\"file %s: line %d: uncaught error: %s (%s, %d)\""));
ccritical.add_argument (new CCodeConstant ("__FILE__"));
methods/contains.vala \
methods/iterator.vala \
methods/parameter-fixed-array-initializer.vala \
+ methods/parameter-out-free-on-error.vala \
methods/parameter-ref-array-resize.vala \
methods/parameter-ref-array-resize-captured.vala \
methods/parameter-ref-delegate.vala \
asynchronous/closures.vala \
asynchronous/constructor-argument-check.vala \
asynchronous/generator.vala \
+ asynchronous/out-parameter-free-on-error.vala \
asynchronous/result-pos.vala \
asynchronous/variadic-invalid.test \
asynchronous/variadic-invalid-2.test \
--- /dev/null
+errordomain FooError {
+ FAIL
+}
+
+class Manam : Object {
+}
+
+async void foo_async (Manam i, out Manam o) throws FooError {
+ o = i;
+ throw new FooError.FAIL ("foo");
+}
+
+async void run () {
+ var manam = new Manam ();
+ assert (manam.ref_count == 1);
+ try {
+ Manam minim;
+ yield foo_async (manam, out minim);
+ } catch {
+ }
+ assert (manam.ref_count == 2);
+ loop.quit ();
+}
+
+MainLoop loop;
+
+void main () {
+ loop = new MainLoop ();
+ run.begin ();
+ loop.run ();
+}
--- /dev/null
+errordomain FooError {
+ FAIL
+}
+
+class Manam : Object {
+}
+
+void foo (Manam i, out Manam o) throws FooError {
+ o = i;
+ throw new FooError.FAIL ("foo");
+}
+
+void bar (Manam i, out unowned Manam o) throws FooError {
+ o = i;
+ throw new FooError.FAIL ("bar");
+}
+
+void main () {
+ {
+ var manam = new Manam ();
+ assert (manam.ref_count == 1);
+ try {
+ Manam minim;
+ foo (manam, out minim);
+ } catch (FooError e) {
+ }
+ assert (manam.ref_count == 1);
+ }
+ {
+ var manam = new Manam ();
+ assert (manam.ref_count == 1);
+ try {
+ unowned Manam minim;
+ bar (manam, out minim);
+ } catch (FooError e) {
+ }
+ assert (manam.ref_count == 1);
+ }
+}