[vala] codegen: Destroy value of "as" cast in case the result is null
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] codegen: Destroy value of "as" cast in case the result is null
- Date: Fri, 22 Mar 2013 21:48:47 +0000 (UTC)
commit fd55b251c171d89bb5754b601f4a99981d0b3916
Author: Luca Bruno <lucabru src gnome org>
Date: Wed Mar 20 23:32:19 2013 +0000
codegen: Destroy value of "as" cast in case the result is null
Fixes bug 695671.
codegen/valaccodebasemodule.vala | 26 +++++++++++++++++++++-----
tests/Makefile.am | 1 +
tests/objects/bug695671.vala | 37 +++++++++++++++++++++++++++++++++++++
3 files changed, 59 insertions(+), 5 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 93d04ee..a8d9e8c 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)) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index eedf8ce..c11565c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -131,6 +131,7 @@ TESTS = \
objects/bug664529.vala \
objects/bug667668.vala \
objects/bug683646.vala \
+ objects/bug695671.vala \
errors/errors.vala \
errors/bug567181.vala \
errors/bug579101.vala \
diff --git a/tests/objects/bug695671.vala b/tests/objects/bug695671.vala
new file mode 100644
index 0000000..fb06be9
--- /dev/null
+++ b/tests/objects/bug695671.vala
@@ -0,0 +1,37 @@
+class Foo : Object {
+}
+
+G ref_generic<G> (G o) {
+ return o;
+}
+
+Object ref (Object o) {
+ return o;
+}
+
+void main () {
+ var o = new Object();
+ var f = (ref (o)) as Foo;
+ assert (f == null);
+ assert (o.ref_count == 1);
+
+ var g = (ref_generic (o)) as Foo;
+ assert (g == null);
+ assert (o.ref_count == 1);
+
+ var r = ref_generic (o) as Object;
+ assert (r == o);
+ assert (o.ref_count == 2);
+
+ var r2 = o as Object;
+ assert (r2 == o);
+ assert (o.ref_count == 3);
+
+ unowned Object r3 = o as Object;
+ assert (r3 == o);
+ assert (o.ref_count == 3);
+
+ unowned Object r4 = o as Foo;
+ assert (r4 == null);
+ assert (o.ref_count == 3);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]