[vala] codegen: Guard access to out parameters to allow null arguments
- From: Jürg Billeter <juergbi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] codegen: Guard access to out parameters to allow null arguments
- Date: Sat, 16 Oct 2010 10:41:17 +0000 (UTC)
commit 2444fce618821a1a20fd0549da5b3981574654cd
Author: Jürg Billeter <j bitron ch>
Date: Sat Oct 16 12:26:16 2010 +0200
codegen: Guard access to out parameters to allow null arguments
Fixes bug 591673.
codegen/valaccodebasemodule.vala | 41 ++++++++++++++++++++++++++++++
codegen/valaccodememberaccessmodule.vala | 31 ++++++++++++++--------
codegen/valaccodemethodmodule.vala | 39 ++++++++++++++++++++--------
3 files changed, 89 insertions(+), 22 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index a8ec581..57a30fe 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -3269,6 +3269,47 @@ public class Vala.CCodeBaseModule : CodeGenerator {
ccode.add_expression (new CCodeAssignment (result_lhs, get_cvalue (stmt.return_expression)));
}
+ if (current_method != null && !current_method.coroutine) {
+ // assign values to output parameters if they are not NULL
+ // otherwise, free the value if necessary
+ foreach (var param in current_method.get_parameters ()) {
+ if (param.direction != ParameterDirection.OUT) {
+ continue;
+ }
+
+ var delegate_type = param.variable_type as DelegateType;
+
+ ccode.open_if (get_variable_cexpression (param.name));
+ ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (param.name)), get_variable_cexpression ("_" + param.name)));
+
+ if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
+ ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (get_delegate_target_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname ("_" + param.name)))));
+ if (delegate_type.value_owned) {
+ ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (get_delegate_target_destroy_notify_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname ("_" + param.name)))));
+ }
+ }
+
+ if (param.variable_type.is_disposable ()){
+ ccode.add_else ();
+ var ma = new MemberAccess (null, param.name);
+ ma.symbol_reference = param;
+ ma.value_type = param.variable_type.copy ();
+ visit_member_access (ma);
+ ccode.add_expression (get_unref_expression (get_variable_cexpression ("_" + param.name), param.variable_type, ma));
+ }
+ ccode.close ();
+
+ var array_type = param.variable_type as ArrayType;
+ if (array_type != null && !array_type.fixed_length && !param.no_array_length) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ ccode.open_if (get_variable_cexpression (get_parameter_array_length_cname (param, dim)));
+ ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (get_parameter_array_length_cname (param, dim))), new CCodeIdentifier (get_array_length_cname (get_variable_cname ("_" + param.name), dim))));
+ ccode.close ();
+ }
+ }
+ }
+ }
+
// free local variables
append_local_free (current_symbol);
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 0bbb551..c17a6f6 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -535,6 +535,8 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
}
} else {
+ string name = p.name;
+
if (p.captured) {
// captured variables are stored on the heap
var block = p.parent_symbol as Block;
@@ -559,9 +561,14 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
} else {
var type_as_struct = p.variable_type.data_type as Struct;
- if (p.direction != ParameterDirection.IN
- || (type_as_struct != null && !type_as_struct.is_simple_type () && !p.variable_type.nullable)) {
- set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_variable_cname (p.name))));
+
+ if (p.direction == ParameterDirection.OUT) {
+ name = "_" + name;
+ }
+
+ if (p.direction == ParameterDirection.REF
+ || (p.direction == ParameterDirection.IN && type_as_struct != null && !type_as_struct.is_simple_type () && !p.variable_type.nullable)) {
+ set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_variable_cname (name))));
} else {
// Property setters of non simple structs shall replace all occurences
// of the "value" formal parameter with a dereferencing version of that
@@ -573,14 +580,14 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
!current_property_accessor.prop.property_type.nullable) {
set_cvalue (expr, new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("value")));
} else {
- set_cvalue (expr, get_variable_cexpression (p.name));
+ set_cvalue (expr, get_variable_cexpression (name));
}
}
if (p.variable_type is DelegateType) {
- CCodeExpression target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (p.name)));
- CCodeExpression delegate_target_destroy_notify = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (p.name)));
- if (p.direction != ParameterDirection.IN) {
- // accessing argument of out/ref param
+ CCodeExpression target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (name)));
+ CCodeExpression delegate_target_destroy_notify = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (name)));
+ if (p.direction == ParameterDirection.REF) {
+ // accessing argument of ref param
target_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, target_expr);
delegate_target_destroy_notify = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, delegate_target_destroy_notify);
}
@@ -592,7 +599,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
if (!p.captured && array_type != null) {
if (p.array_null_terminated) {
- var carray_expr = get_variable_cexpression (p.name);
+ var carray_expr = get_variable_cexpression (name);
requires_array_length = true;
var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
len_call.add_argument (carray_expr);
@@ -600,8 +607,10 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
} else if (!p.no_array_length) {
for (int dim = 1; dim <= array_type.rank; dim++) {
CCodeExpression length_expr = get_variable_cexpression (get_parameter_array_length_cname (p, dim));
- if (p.direction != ParameterDirection.IN) {
- // accessing argument of out/ref param
+ if (p.direction == ParameterDirection.OUT) {
+ length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (name), dim));
+ } else if (p.direction == ParameterDirection.REF) {
+ // accessing argument of ref param
length_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, length_expr);
}
append_array_size (expr, length_expr);
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 106b0aa..a7e7fd7 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -444,22 +444,39 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
create_method_type_check_statement (m, creturn_type, t, !param.variable_type.nullable, get_variable_cname (param.name));
}
} else if (!m.coroutine) {
- var t = param.variable_type.data_type;
- if ((t != null && t.is_reference_type ()) || param.variable_type is ArrayType) {
- // ensure that the passed reference for output parameter is cleared
- var a = new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (param.name)), new CCodeConstant ("NULL"));
- var cblock = new CCodeBlock ();
- cblock.add_statement (new CCodeExpressionStatement (a));
-
- var condition = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_variable_cexpression (param.name), new CCodeConstant ("NULL"));
- var if_statement = new CCodeIfStatement (condition, cblock);
- ccode.add_statement (if_statement);
+ // declare local variable for out parameter to allow assignment even when caller passes NULL
+ var vardecl = new CCodeVariableDeclarator.zero (get_variable_cname ("_" + param.name), default_value_for_type (param.variable_type, true));
+ ccode.add_declaration (param.variable_type.get_cname (), vardecl);
+
+ if (param.variable_type is ArrayType) {
+ // create variables to store array dimensions
+ var array_type = (ArrayType) param.variable_type;
+
+ if (!array_type.fixed_length) {
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ vardecl = new CCodeVariableDeclarator.zero (get_array_length_cname (get_variable_cname ("_" + param.name), dim), new CCodeConstant ("0"));
+ ccode.add_declaration ("int", vardecl);
+ }
+ }
+ } else if (param.variable_type is DelegateType) {
+ var deleg_type = (DelegateType) param.variable_type;
+ var d = deleg_type.delegate_symbol;
+ if (d.has_target) {
+ // create variable to store delegate target
+ vardecl = new CCodeVariableDeclarator.zero (get_delegate_target_cname (get_variable_cname ("_" + param.name)), new CCodeConstant ("NULL"));
+ ccode.add_declaration ("void *", vardecl);
+
+ if (deleg_type.value_owned) {
+ vardecl = new CCodeVariableDeclarator.zero (get_delegate_target_destroy_notify_cname (get_variable_cname ("_" + param.name)), new CCodeConstant ("NULL"));
+ ccode.add_declaration ("GDestroyNotify", vardecl);
+ }
+ }
}
}
}
if (!(m.return_type is VoidType) && !m.return_type.is_real_non_null_struct_type () && !m.coroutine) {
- var vardecl = new CCodeVariableDeclarator ("result", default_value_for_type (m.return_type, true));
+ var vardecl = new CCodeVariableDeclarator ("result", default_value_for_type (m.return_type, true));
vardecl.init0 = true;
ccode.add_declaration (m.return_type.get_cname (), vardecl);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]