[vala/wip/effectfree: 44/44] codegen: Use GLibValue.lvalue when taking the address of an expression



commit 726e59564b6db28c7651c76eae11496b6cf61c18
Author: Luca Bruno <lucabru src gnome org>
Date:   Sun Jun 19 09:11:59 2011 +0200

    codegen: Use GLibValue.lvalue when taking the address of an expression
    
    Fixes bug 648364.

 codegen/valaccodebasemodule.vala         |   44 +++++++++++-------------------
 codegen/valaccodememberaccessmodule.vala |   16 +++--------
 codegen/valaccodemethodcallmodule.vala   |   21 ++++----------
 tests/Makefile.am                        |    1 +
 tests/basic-types/bug648364.vala         |    5 +++
 5 files changed, 32 insertions(+), 55 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 3b747ef..31870bb 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -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;
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index b34290f..e09bb2a 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -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);
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index ddfb4fc..2d615b7 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -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);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 708132a..d672835 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
index 0000000..7ee2340
--- /dev/null
+++ b/tests/basic-types/bug648364.vala
@@ -0,0 +1,5 @@
+static const int foo = 3;
+
+void main() {
+        int? bar = foo;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]