]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Use GLibValue.lvalue when taking the address of an expression
authorLuca Bruno <lucabru@src.gnome.org>
Sun, 19 Jun 2011 07:11:59 +0000 (09:11 +0200)
committerLuca Bruno <lucabru@src.gnome.org>
Wed, 6 Jul 2011 21:08:17 +0000 (23:08 +0200)
Fixes bug 648364.

codegen/valaccodebasemodule.vala
codegen/valaccodememberaccessmodule.vala
codegen/valaccodemethodcallmodule.vala
tests/Makefile.am
tests/basic-types/bug648364.vala [new file with mode: 0644]

index 3b747efe18b71b24c317efe8e03cb234d2483d5b..31870bb70ad628bf1e0624767c4e308b0c06e07b 100644 (file)
@@ -5136,22 +5136,15 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                } else if (boxing) {
                        // value needs to be boxed
 
-                       var unary = result.cvalue as CCodeUnaryExpression;
-                       if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) {
-                               // *expr => expr
-                               result.cvalue = unary.inner;
-                       } else if (result.cvalue is CCodeIdentifier || result.cvalue is CCodeMemberAccess) {
-                               result.cvalue = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, result.cvalue);
-                       } else {
-                               var cast_type = target_type.copy ();
-                               cast_type.nullable = false;
-                               var decl = get_temp_variable (cast_type, cast_type.value_owned, node, false);
-                               emit_temp_var (decl);
-
-                               ccode.add_assignment (get_variable_cexpression (decl.name), get_implicit_cast_expression (result.cvalue, type, cast_type, node));
-                               result.cvalue = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (decl.name));
+                       result.value_type.nullable = false;
+                       if (!result.lvalue || !result.value_type.equals (value.value_type)) {
+                               result.cvalue = get_implicit_cast_expression (result.cvalue, value.value_type, result.value_type, node);
+                               result = (GLibValue) store_temp_value (result, node);
                                requires_temp_value = false;
                        }
+                       result.cvalue = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, result.cvalue);
+                       result.lvalue = false;
+                       result.value_type.nullable = true;
                } else if (unboxing) {
                        // unbox value
 
@@ -5269,20 +5262,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
                        if (prop.parent_symbol is Struct) {
                                // we need to pass struct instance by reference
-                               var unary = cinstance as CCodeUnaryExpression;
-                               if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) {
-                                       // *expr => expr
-                                       cinstance = unary.inner;
-                               } else if (cinstance is CCodeIdentifier || cinstance is CCodeMemberAccess) {
-                                       cinstance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cinstance);
-                               } else {
-                                       // if instance is e.g. a function call, we can't take the address of the expression
-                                       // (tmp = expr, &tmp)
-
-                                       var temp_value = create_temp_value (instance.target_type, false, instance);
-                                       store_value (temp_value, instance.target_value);
-                                       cinstance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_cvalue_ (temp_value));
+                               var instance_value = instance.target_value;
+                               if (!get_lvalue (instance_value)) {
+                                       instance_value = store_temp_value (instance_value, instance);
                                }
+                               cinstance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_cvalue_ (instance_value));
                        }
 
                        ccall.add_argument (cinstance);
@@ -5728,12 +5712,16 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                return glib_value.array_length_cvalues;
        }
 
+       public bool get_lvalue (TargetValue value) {
+               var glib_value = (GLibValue) value;
+               return glib_value.lvalue;
+       }
+
        public bool get_non_null (TargetValue value) {
                var glib_value = (GLibValue) value;
                return glib_value.non_null;
        }
 
-
        public string? get_ctype (TargetValue value) {
                var glib_value = (GLibValue) value;
                return glib_value.ctype;
index b34290fc68ea60cfa0c803cb3d7e98419be6aba3..e09bb2a93d29e2c77280647f887c59f3ce968a69 100644 (file)
@@ -211,19 +211,11 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                if (prop.binding == MemberBinding.INSTANCE) {
                                        if (prop.parent_symbol is Struct) {
                                                // we need to pass struct instance by reference
-                                               var unary = pub_inst as CCodeUnaryExpression;
-                                               if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) {
-                                                       // *expr => expr
-                                                       pub_inst = unary.inner;
-                                               } else if (pub_inst is CCodeIdentifier || pub_inst is CCodeMemberAccess) {
-                                                       pub_inst = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, pub_inst);
-                                               } else {
-                                                       // if instance is e.g. a function call, we can't take the address of the expression
-                                                       var temp_var = get_temp_variable (expr.inner.target_type, true, null, false);
-                                                       emit_temp_var (temp_var);
-                                                       ccode.add_assignment (get_variable_cexpression (temp_var.name), pub_inst);
-                                                       pub_inst = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name));
+                                               var instance = expr.inner.target_value;
+                                               if (!get_lvalue (instance)) {
+                                                       instance = store_temp_value (instance, expr);
                                                }
+                                               pub_inst = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_cvalue_ (instance));
                                        }
 
                                        ccall.add_argument (pub_inst);
index ddfb4fc7e2de0a938a3cc44cb06c9a0006377d3b..2d615b72375ac8204d0bc863969be72af0d15eb5 100644 (file)
@@ -178,29 +178,20 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                        in_arg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
                        out_arg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
                } else if (m != null && m.binding == MemberBinding.INSTANCE && !(m is CreationMethod)) {
-                       instance = get_cvalue (ma.inner);
-
+                       var instance_value = ma.inner.target_value;
                        if ((ma.member_name == "begin" || ma.member_name == "end") && ma.inner.symbol_reference == ma.symbol_reference) {
                                var inner_ma = (MemberAccess) ma.inner;
-                               instance = get_cvalue (inner_ma.inner);
+                               instance_value = inner_ma.inner.target_value;
                        }
+                       instance = get_cvalue_ (instance_value);
 
                        var st = m.parent_symbol as Struct;
                        if (st != null && !st.is_simple_type ()) {
                                // we need to pass struct instance by reference
-                               var unary = instance as CCodeUnaryExpression;
-                               if (unary != null && unary.operator == CCodeUnaryOperator.POINTER_INDIRECTION) {
-                                       // *expr => expr
-                                       instance = unary.inner;
-                               } else if (instance is CCodeIdentifier || instance is CCodeMemberAccess) {
-                                       instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance);
-                               } else {
-                                       // if instance is e.g. a function call, we can't take the address of the expression
-                                       var temp_var = get_temp_variable (ma.inner.target_type, true, null, false);
-                                       emit_temp_var (temp_var);
-                                       ccode.add_assignment (get_variable_cexpression (temp_var.name), instance);
-                                       instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name));
+                               if (!get_lvalue (instance_value)) {
+                                       instance_value = store_temp_value (instance_value, expr);
                                }
+                               instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_cvalue_ (instance_value));
                        }
 
                        in_arg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
index 708132af0db64762d4526ca4ff18025611093d58..d67283558cd0117de6e099db2c42220e4aa85b3d 100644 (file)
@@ -25,6 +25,7 @@ TESTS = \
        basic-types/bug596637.vala \
        basic-types/bug596785.vala \
        basic-types/bug632322.vala \
+       basic-types/bug648364.vala \
        basic-types/bug650993.vala \
        basic-types/bug652380.vala \
        namespaces.vala \
diff --git a/tests/basic-types/bug648364.vala b/tests/basic-types/bug648364.vala
new file mode 100644 (file)
index 0000000..7ee2340
--- /dev/null
@@ -0,0 +1,5 @@
+static const int foo = 3;
+
+void main() {
+        int? bar = foo;
+}