summaryrefslogtreecommitdiff
path: root/codegen
diff options
context:
space:
mode:
authorLuca Bruno <lucabru@src.gnome.org>2013-03-20 23:32:19 +0000
committerLuca Bruno <lucabru@src.gnome.org>2013-03-22 22:48:15 +0100
commitfd55b251c171d89bb5754b601f4a99981d0b3916 (patch)
tree90d6df002dad2a465045844075232270a01efbcc /codegen
parent6756ea97eb06dadb6b1328d0f6019290deb3416e (diff)
downloadvala-fd55b251c171d89bb5754b601f4a99981d0b3916.tar.gz
codegen: Destroy value of "as" cast in case the result is null
Fixes bug 695671.
Diffstat (limited to 'codegen')
-rw-r--r--codegen/valaccodebasemodule.vala26
1 files changed, 21 insertions, 5 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 93d04eeec..a8d9e8cca 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -3200,8 +3200,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
return destroy_value (get_field_cvalue (field, instance));
}
- // logic in this method is temporarily duplicated in destroy_variable
- // apply changes to both methods
public virtual CCodeExpression destroy_value (TargetValue value, bool is_macro_definition = false) {
var type = value.value_type;
if (value.actual_value_type != null) {
@@ -3757,6 +3755,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
(st == null || get_ccode_name (st) != "va_list")) {
// GArray and va_list don't use pointer-based generics
set_cvalue (expr, convert_from_generic_pointer (get_cvalue (expr), expr.value_type));
+ ((GLibValue) expr.target_value).lvalue = false;
}
}
@@ -3775,6 +3774,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
if (expr.formal_target_type.type_parameter.parent_symbol != garray_type) {
// GArray doesn't use pointer-based generics
set_cvalue (expr, convert_to_generic_pointer (get_cvalue (expr), expr.target_type));
+ ((GLibValue) expr.target_value).lvalue = false;
}
}
@@ -5015,12 +5015,25 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
if (iface != null || (cl != null && !cl.is_compact)) {
// checked cast for strict subtypes of GTypeInstance
if (expr.is_silent_cast) {
- var cexpr = get_cvalue (expr.inner);
+ TargetValue to_cast = expr.inner.target_value;
+ CCodeExpression cexpr;
+ if (!get_lvalue (to_cast)) {
+ to_cast = store_temp_value (to_cast, expr);
+ }
+ cexpr = get_cvalue_ (to_cast);
var ccheck = create_type_check (cexpr, expr.type_reference);
var ccast = new CCodeCastExpression (cexpr, get_ccode_name (expr.type_reference));
var cnull = new CCodeConstant ("NULL");
-
- set_cvalue (expr, new CCodeConditionalExpression (ccheck, ccast, cnull));
+ var cast_value = new GLibValue (expr.value_type, new CCodeConditionalExpression (ccheck, ccast, cnull));
+ if (requires_destroy (expr.inner.value_type)) {
+ var casted = store_temp_value (cast_value, expr);
+ ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, get_cvalue_ (casted), new CCodeConstant ("NULL")));
+ ccode.add_expression (destroy_value (to_cast));
+ ccode.close ();
+ expr.target_value = ((GLibValue) casted).copy ();
+ } else {
+ expr.target_value = cast_value;
+ }
} else {
set_cvalue (expr, generate_instance_cast (get_cvalue (expr.inner), expr.type_reference.data_type));
}
@@ -5632,7 +5645,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
result.cvalue = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, result.cvalue);
} else {
+ // TODO: rewrite get_implicit_cast_expression to return a GLibValue
+ var old_cexpr = result.cvalue;
result.cvalue = get_implicit_cast_expression (result.cvalue, type, target_type, node);
+ result.lvalue = result.lvalue && result.cvalue == old_cexpr;
}
if (requires_temp_value && !(target_type is ArrayType && ((ArrayType) target_type).inline_allocated)) {