diff --git a/gobject/valaccodememberaccessmodule.vala b/gobject/valaccodememberaccessmodule.vala
index b061106..ab4708a 100644
--- a/gobject/valaccodememberaccessmodule.vala
+++ b/gobject/valaccodememberaccessmodule.vala
@@ -98,6 +98,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 
 				var cl = instance_target_type.data_type as Class;
 				bool is_gtypeinstance = ((instance_target_type.data_type == cl) && (cl == null || !cl.is_compact));
+				var st = instance_target_type.data_type as Struct;
 
 				CCodeExpression inst;
 				if (is_gtypeinstance && f.access == SymbolAccessibility.PRIVATE) {
@@ -108,7 +109,37 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 				if (instance_target_type.data_type.is_reference_type () || (expr.inner != null && expr.inner.value_type is PointerType)) {
 					expr.ccodenode = new CCodeMemberAccess.pointer (inst, f.get_cname ());
 				} else {
-					expr.ccodenode = new CCodeMemberAccess (inst, f.get_cname ());
+					bool found_in_parent = false;
+					string cname = f.get_cname ();
+					if (st != null && base_type != null) {
+						// recurse through the parents of a struct to access the desired field
+						Scope lookup_scope = base_type.data_type.scope;
+
+						if (lookup_scope.lookup (cname) != null) {
+							expr.ccodenode = new CCodeMemberAccess (inst, "parent_struct");
+						} else {
+							lookup_scope = ((Struct) lookup_scope.owner).base_type.data_type.scope;
+							var parent_struct = new CCodeMemberAccess (inst, "parent_struct");
+							while (lookup_scope != null) {
+								if (lookup_scope.lookup (cname) != null) {
+									expr.ccodenode = new CCodeMemberAccess (parent_struct, cname);
+									found_in_parent = true;
+									break;
+								}
+								if (!(lookup_scope.owner is Struct) || ((Struct) lookup_scope.owner).base_type == null) {
+									break;
+								}
+								lookup_scope = ((Struct) lookup_scope.owner).base_type.data_type.scope;
+								parent_struct = new CCodeMemberAccess (parent_struct, "parent_struct");
+							}
+							if (!found_in_parent) {
+								assert_not_reached ();
+							}
+						}
+					}
+					if (!found_in_parent) {
+						expr.ccodenode = new CCodeMemberAccess (inst, cname);
+					}
 				}
 			} else if (f.binding == MemberBinding.CLASS) {
 				var cl = (Class) f.parent_symbol;
diff --git a/gobject/valaccodemethodcallmodule.vala b/gobject/valaccodemethodcallmodule.vala
index 2f10155..d1fd053 100644
--- a/gobject/valaccodemethodcallmodule.vala
+++ b/gobject/valaccodemethodcallmodule.vala
@@ -121,6 +121,10 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 					instance = unary.inner;
 				} else if (instance is CCodeIdentifier || instance is CCodeMemberAccess) {
 					instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance);
+					var inst_var = ma.inner as MemberAccess;
+					if (inst_var != null && st != inst_var.value_type.data_type) {
+						instance = new CCodeCastExpression (instance, "%s*".printf (st.get_full_name ()));
+					}
 				} else {
 					// if instance is e.g. a function call, we can't take the address of the expression
 					// (tmp = expr, &tmp)
diff --git a/gobject/valaccodestructmodule.vala b/gobject/valaccodestructmodule.vala
index 24675bb..28324a4 100644
--- a/gobject/valaccodestructmodule.vala
+++ b/gobject/valaccodestructmodule.vala
@@ -34,6 +34,9 @@ public class Vala.CCodeStructModule : CCodeBaseModule {
 		var old_instance_finalize_fragment = instance_finalize_fragment;
 		current_type_symbol = st;
 		instance_struct = new CCodeStruct ("_%s".printf (st.get_cname ()));
+		if (st.base_type != null) {
+			instance_struct.add_field (st.base_type.data_type.get_cname (), "parent_struct");
+		}
 		instance_finalize_fragment = new CCodeFragment ();
 
 		CCodeFragment decl_frag;
