Merge into master from pull request #342:
loci: begin removing inheritance unions (https://github.com/floodlight/loxigen/pull/342)
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index b708c65..239034a 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -1076,13 +1076,13 @@
             e_type = loxi_utils.list_to_entry_type(cls)
             out.write("""
 extern int %(cls)s_first(
-    %(cls)s_t *list, %(e_type)s_t *obj);
+    %(cls)s_t *list, of_list_iter_t iter);
 extern int %(cls)s_next(
-    %(cls)s_t *list, %(e_type)s_t *obj);
+    %(cls)s_t *list, of_list_iter_t iter);
 extern int %(cls)s_append_bind(
-    %(cls)s_t *list, %(e_type)s_t *obj);
+    %(cls)s_t *list, of_list_iter_t iter);
 extern int %(cls)s_append(
-    %(cls)s_t *list, %(e_type)s_t *obj);
+    %(cls)s_t *list, of_list_iter_t iter);
 
 /**
  * Iteration macro for list of type %(cls)s
@@ -1556,10 +1556,6 @@
     @param cls The class name for the function
     @param out The file to which to write
     """
-    if type_maps.class_is_inheritance_root(cls):
-        param = "obj_p"
-    else:
-        param = "obj"
 
     out.write("""
 /**
@@ -1580,20 +1576,9 @@
  */
 
 void
-%(cls)s_init(%(cls)s_t *%(param)s,
+%(cls)s_init(of_object_t *obj,
     of_version_t version, int bytes, int clean_wire)
 {
-""" % dict(cls=cls, param=param))
-
-    # Use an extra pointer to deal with inheritance classes
-    if type_maps.class_is_inheritance_root(cls):
-        out.write("""\
-    %s_header_t *obj;
-
-    obj = &obj_p->header;  /* Need instantiable subclass */
-""" % cls)
-
-    out.write("""
     LOCI_ASSERT(of_object_fixed_len[version][%(enum)s] >= 0);
     if (clean_wire) {
         MEMSET(obj, 0, sizeof(*obj));
@@ -1604,9 +1589,7 @@
     obj->version = version;
     obj->length = bytes;
     obj->object_id = %(enum)s;
-""" % dict(cls=cls, enum=enum_name(cls)))
 
-    out.write("""
     /* Grow the wire buffer */
     if (obj->wbuf != NULL) {
         int tot_bytes;
@@ -1615,8 +1598,7 @@
         of_wire_buffer_grow(obj->wbuf, tot_bytes);
     }
 }
-
-""")
+""" % dict(cls=cls, enum=enum_name(cls)))
 
 def gen_new_fn_body(cls, out):
     """
@@ -1648,15 +1630,15 @@
  * \\ingroup %(cls)s
  */
 
-%(cls)s_t *
+of_object_t *
 %(cls)s_new(of_version_t version)
 {
-    %(cls)s_t *obj;
+    of_object_t *obj;
     int bytes;
 
     bytes = of_object_fixed_len[version][%(enum)s];
 
-    if ((obj = (%(cls)s_t *)of_object_new(%(max_length)s)) == NULL) {
+    if ((obj = of_object_new(%(max_length)s)) == NULL) {
         return NULL;
     }
 
@@ -1717,11 +1699,11 @@
 
     for cls in of_g.standard_class_order:
         out.write("""
-extern %(cls)s_t *
+extern of_object_t *
     %(cls)s_new(of_version_t version);
 """ % dict(cls=cls))
         out.write("""extern void %(cls)s_init(
-    %(cls)s_t *obj, of_version_t version, int bytes, int clean_wire);
+    of_object_t *obj, of_version_t version, int bytes, int clean_wire);
 """ % dict(cls=cls))
 
     out.write("""
@@ -1743,8 +1725,8 @@
  * \ingroup %(cls)s
  */
 static inline void
-%(cls)s_delete(%(cls)s_t *obj) {
-    of_object_delete((of_object_t *)(obj));
+%(cls)s_delete(of_object_t *obj) {
+    of_object_delete(obj);
 }
 """ % dict(cls=cls))
 
diff --git a/c_gen/c_dump_gen.py b/c_gen/c_dump_gen.py
index 4e7db7a..a9074af 100644
--- a/c_gen/c_dump_gen.py
+++ b/c_gen/c_dump_gen.py
@@ -93,7 +93,7 @@
             if type_maps.class_is_inheritance_root(cls):
                 continue
             out.write("""\
-int %(cls)s_%(ver_name)s_dump(loci_writer_f writer, void* cookie, %(cls)s_t *obj);
+int %(cls)s_%(ver_name)s_dump(loci_writer_f writer, void* cookie, of_object_t *obj);
 """ % dict(cls=cls, ver_name=loxi_utils.version_to_name(version)))
 
     out.write("""
@@ -133,7 +133,7 @@
                 continue
             out.write("""
 int
-%(cls)s_%(ver_name)s_dump(loci_writer_f writer, void* cookie, %(cls)s_t *obj)
+%(cls)s_%(ver_name)s_dump(loci_writer_f writer, void* cookie, of_object_t *obj)
 {
     int out = 0;
 """ % dict(cls=cls, ver_name=ver_name))
@@ -150,7 +150,7 @@
 """  % dict(m_type=m_type, v_name=var_name_map(m_type)))
                     if loxi_utils.class_is_list(m_type):
                         base_type = loxi_utils.list_to_entry_type(m_type)
-                        out.write("    %s elt;\n    int rv;\n" % base_type)
+                        out.write("    of_object_t elt;\n    int rv;\n")
             out.write("""
     out += writer(cookie, "Object of type %(cls)s\\n");
 """ % dict(cls=cls))
diff --git a/c_gen/c_match.py b/c_gen/c_match.py
index e5a41ef..a703e4f 100644
--- a/c_gen/c_match.py
+++ b/c_gen/c_match.py
@@ -458,7 +458,7 @@
 static int
 populate_oxm_list(of_match_t *src, of_list_oxm_t *oxm_list)
 {
-    of_oxm_t oxm_entry;
+    of_object_t elt;
 
     /* For each active member, add an OXM entry to the list */
 """)
@@ -466,23 +466,18 @@
         out.write("""\
     if (OF_MATCH_MASK_%(ku)s_ACTIVE_TEST(src)) {
         if (!OF_MATCH_MASK_%(ku)s_EXACT_TEST(src)) {
-            of_oxm_%(key)s_masked_t *elt;
-            elt = &oxm_entry.%(key)s_masked;
-
-            of_oxm_%(key)s_masked_init(elt,
+            of_oxm_%(key)s_masked_init(&elt,
                 oxm_list->version, -1, 1);
-            of_list_oxm_append_bind(oxm_list, &oxm_entry);
-            of_oxm_%(key)s_masked_value_set(elt,
+            of_list_oxm_append_bind(oxm_list, &elt);
+            of_oxm_%(key)s_masked_value_set(&elt,
                    src->fields.%(key)s);
-            of_oxm_%(key)s_masked_value_mask_set(elt,
+            of_oxm_%(key)s_masked_value_mask_set(&elt,
                    src->masks.%(key)s);
         } else {  /* Active, but not masked */
-            of_oxm_%(key)s_t *elt;
-            elt = &oxm_entry.%(key)s;
-            of_oxm_%(key)s_init(elt,
+            of_oxm_%(key)s_init(&elt,
                 oxm_list->version, -1, 1);
-            of_list_oxm_append_bind(oxm_list, &oxm_entry);
-            of_oxm_%(key)s_value_set(elt, src->fields.%(key)s);
+            of_list_oxm_append_bind(oxm_list, &elt);
+            of_oxm_%(key)s_value_set(&elt, src->fields.%(key)s);
         }
     }
 """ % dict(key=key, ku=key.upper()))
@@ -629,7 +624,7 @@
 {
     int rv;
     of_list_oxm_t oxm_list;
-    of_oxm_t oxm_entry;
+    of_object_t oxm_entry;
 """)
 #    for key in match.of_match_members:
 #        out.write("    of_oxm_%s_t *%s;\n" % (key, key))
@@ -643,23 +638,23 @@
     rv = of_list_oxm_first(&oxm_list, &oxm_entry);
 
     while (rv == OF_ERROR_NONE) {
-        switch (oxm_entry.header.object_id) { /* What kind of entry is this */
+        switch (oxm_entry.object_id) { /* What kind of entry is this */
 """)
     for key in match.of_match_members:
         out.write("""
         case OF_OXM_%(ku)s_MASKED:
             of_oxm_%(key)s_masked_value_mask_get(
-                &oxm_entry.%(key)s_masked,
+                &oxm_entry,
                 &dst->masks.%(key)s);
             of_oxm_%(key)s_masked_value_get(
-                &oxm_entry.%(key)s,
+                &oxm_entry,
                 &dst->fields.%(key)s);
             of_memmask(&dst->fields.%(key)s, &dst->masks.%(key)s, sizeof(&dst->fields.%(key)s));
             break;
         case OF_OXM_%(ku)s:
             OF_MATCH_MASK_%(ku)s_EXACT_SET(dst);
             of_oxm_%(key)s_value_get(
-                &oxm_entry.%(key)s,
+                &oxm_entry,
                 &dst->fields.%(key)s);
             break;
 """ % (dict(ku=key.upper(), key=key)))
diff --git a/c_gen/c_show_gen.py b/c_gen/c_show_gen.py
index 9a13b43..a25e366 100644
--- a/c_gen/c_show_gen.py
+++ b/c_gen/c_show_gen.py
@@ -166,7 +166,7 @@
             if type_maps.class_is_inheritance_root(cls):
                 continue
             out.write("""\
-int %(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, %(cls)s_t *obj);
+int %(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, of_object_t *obj);
 """ % dict(cls=cls, ver_name=loxi_utils.version_to_name(version)))
 
     out.write("""
@@ -206,7 +206,7 @@
                 continue
             out.write("""
 int
-%(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, %(cls)s_t *obj)
+%(cls)s_%(ver_name)s_show(loci_writer_f writer, void* cookie, of_object_t *obj)
 {
     int out = 0;
 """ % dict(cls=cls, ver_name=ver_name))
@@ -222,8 +222,7 @@
     %(m_type)s %(v_name)s;
 """  % dict(m_type=m_type, v_name=var_name_map(m_type)))
                     if loxi_utils.class_is_list(m_type):
-                        base_type = loxi_utils.list_to_entry_type(m_type)
-                        out.write("    %s elt;\n    int rv;\n" % base_type)
+                        out.write("    of_object_t elt;\n    int rv;\n")
             for member in members:
                 m_type = member["m_type"]
                 m_name = member["name"]
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index db7ca28..5ddd4e9 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -701,6 +701,8 @@
     """
     for version in of_g.of_version_range:
         for cls in of_g.standard_class_order:
+            if type_maps.class_is_inheritance_root(cls):
+                continue
             (members, member_types) = scalar_member_types_get(cls, version)
             scalar_funs_instance(out, cls, version, members, member_types)
 
@@ -710,8 +712,7 @@
     base_type = loxi_utils.list_to_entry_type(cls)
     setup_template = """
     %(subcls)s_init(%(inst)s, %(v_name)s, -1, 1);
-    %(cls)s_append_bind(list,
-            (%(base_type)s_t *)%(inst)s);
+    %(cls)s_append_bind(list, %(inst)s);
     value = %(subcls)s_%(v_name)s_populate(
         %(inst)s, value);
     cur_len += %(inst)s->length;
@@ -772,7 +773,7 @@
 """ % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
     base_type = loxi_utils.list_to_entry_type(cls)
     out.write("""
-    %(base_type)s_t elt;
+    of_object_t elt;
     int cur_len = 0;
     (void) elt;
     (void) cur_len;
@@ -792,7 +793,7 @@
             out.write("    %s_t *%s;\n" % (subcls, instance))
         out.write("\n    /* Instantiate pointers for each subclass */\n")
         for instance, subcls in sub_classes:
-            out.write("    %s = &elt.%s;\n" % (instance, instance))
+            out.write("    %s = &elt;\n" % (instance))
 
     if not type_maps.class_is_virtual(base_type): # No inheritance case
         setup_instance(out, cls, base_type, "elt_p", v_name, version)
@@ -821,7 +822,7 @@
 """ % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
     base_type = loxi_utils.list_to_entry_type(cls)
     out.write("""
-    %(base_type)s_t elt;
+    of_object_t elt;
     (void) elt;
 """ % dict(cls=cls, base_type=base_type))
 
@@ -839,7 +840,7 @@
             out.write("    %s_t *%s;\n" % (subcls, instance))
         out.write("\n    /* Instantiate pointers for each subclass */\n")
         for instance, subcls in sub_classes:
-            out.write("    %s = &elt.%s;\n" % (instance, instance))
+            out.write("    %s = &elt;\n" % (instance))
 
     if not type_maps.class_is_virtual(base_type) or sub_classes:
         out.write("    TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))
@@ -1181,7 +1182,7 @@
 """ % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
     base_type = loxi_utils.list_to_entry_type(cls)
     out.write("""
-    %(base_type)s_t elt;
+    of_object_t elt;
     int cur_len = 0;
     (void) elt;
     (void) cur_len;
@@ -1201,7 +1202,7 @@
             out.write("    %s_t *%s;\n" % (subcls, instance))
         out.write("\n    /* Instantiate pointers for each subclass */\n")
         for instance, subcls in sub_classes:
-            out.write("    %s = &elt.%s;\n" % (instance, instance))
+            out.write("    %s = &elt;\n" % (instance))
 
     if not type_maps.class_is_virtual(base_type): # No inheritance case
         setup_instance(out, cls, base_type, "elt_p", v_name, version)
@@ -1227,7 +1228,7 @@
 """ % dict(cls=cls, v_name=loxi_utils.version_to_name(version)))
     base_type = loxi_utils.list_to_entry_type(cls)
     out.write("""
-    %(base_type)s_t elt;
+    of_object_t elt;
     int count = 0;
     int rv;
 """ % dict(cls=cls, base_type=base_type))
@@ -1249,7 +1250,7 @@
             out.write("    %s_t *%s;\n" % (subcls, instance))
         out.write("\n    /* Instantiate pointers for each subclass */\n")
         for instance, subcls in sub_classes:
-            out.write("    %s = &elt.%s;\n" % (instance, instance))
+            out.write("    %s = &elt;\n" % (instance))
 
     if not type_maps.class_is_virtual(base_type) or sub_classes:
         out.write("    TEST_OK(%(cls)s_first(list, &elt));\n" % dict(cls=cls))
@@ -1661,8 +1662,8 @@
 %(cls)s_%(ver_name)s_dup(
     %(cls)s_t *src)
 {
-    %(elt_type)s_t src_elt;
-    %(elt_type)s_t *dst_elt;
+    of_object_t src_elt;
+    of_object_t *dst_elt;
     int rv;
     %(cls)s_t *dst;
 
@@ -1697,9 +1698,9 @@
  *
  * The caller is responsible for deleting the returned value
  */
-%(cls)s_t *
+of_object_t *
 %(cls)s_%(ver_name)s_dup(
-    %(cls)s_t *src)
+    of_object_t *src)
 {
 """ % dict(cls=cls, ver_name=ver_name))
 
@@ -1708,9 +1709,8 @@
     for (_, sub_cls) in sub_classes:
         sub_enum = sub_cls.upper()
         out.write("""
-    if (src->header.object_id == %(sub_enum)s) {
-        return (%(cls)s_t *)%(sub_cls)s_%(ver_name)s_dup(
-            (of_object_t *)src);
+    if (src->object_id == %(sub_enum)s) {
+        return %(sub_cls)s_%(ver_name)s_dup(src);
     }
 """ % dict(sub_cls=sub_cls, ver_name=ver_name, sub_enum=sub_enum, cls=cls))
 
@@ -1851,22 +1851,21 @@
 
     for cls in of_g.standard_class_order:
         out.write("""
-%(cls)s_t *
+of_object_t *
 %(cls)s_dup(
-    %(cls)s_t *src)
+    of_object_t *src)
 {
 """ % dict(cls=cls))
         for version in of_g.of_version_range:
             if not loxi_utils.class_in_version(cls, version):
                 continue
-            hdr = "header." if type_maps.class_is_inheritance_root(cls) else ""
 
             ver_name = loxi_utils.version_to_name(version)
             out.write("""
-    if (src->%(hdr)sversion == %(ver_name)s) {
+    if (src->version == %(ver_name)s) {
         return %(cls)s_%(ver_name)s_dup(src);
     }
-""" % dict(cls=cls, ver_name=ver_name, hdr=hdr))
+""" % dict(cls=cls, ver_name=ver_name))
 
         out.write("""
     /* Class not supported in given version */
@@ -1920,9 +1919,9 @@
 
     for cls in of_g.standard_class_order:
         out.write("""
-extern %(cls)s_t *
+extern of_object_t *
     %(cls)s_dup(
-        %(cls)s_t *src);
+        of_object_t *src);
 """ % dict(cls=cls))
 
     for version in of_g.of_version_range:
@@ -1931,9 +1930,9 @@
                 continue
             ver_name = loxi_utils.version_to_name(version)
             out.write("""
-extern %(cls)s_t *
+extern of_object_t *
     %(cls)s_%(ver_name)s_dup(
-        %(cls)s_t *src);
+        of_object_t *src);
 """ % dict(cls=cls, ver_name=ver_name))
 
     out.write("\n#endif /* _OF_DUP_H_ */\n")
diff --git a/c_gen/templates/README b/c_gen/templates/README
index 71c4a48..44eedab 100644
--- a/c_gen/templates/README
+++ b/c_gen/templates/README
@@ -60,7 +60,7 @@
     for (i = 1; i <= 4; i++) {
         of_action_output_t action;
         of_action_output_init(&action, flow_add->version, -1, 1);
-        of_list_action_append_bind(&actions, (of_action_t *)&action);
+        of_list_action_append_bind(&actions, &action);
         of_action_output_port_set(&action, i);
     }
 
diff --git a/c_gen/templates/list.c b/c_gen/templates/list.c
index 9ff6e42..d39af9a 100644
--- a/c_gen/templates/list.c
+++ b/c_gen/templates/list.c
@@ -42,12 +42,12 @@
  */
 
 int
-${cls}_first(${cls}_t *list, ${e_cls}_t *_obj)
+${cls}_first(${cls}_t *list, of_list_iter_t iter)
 {
     int rv;
-    of_object_t *obj = (of_object_t *)_obj;
+    of_object_t *obj = iter.obj;
 
-    ${e_cls}_init(_obj, list->version, -1, 1);
+    ${e_cls}_init(obj, list->version, -1, 1);
 
     if ((rv = of_list_first(list, obj)) < 0) {
         return rv;
@@ -73,10 +73,10 @@
  */
 
 int
-${cls}_next(${cls}_t *list, ${e_cls}_t *_obj)
+${cls}_next(${cls}_t *list, of_list_iter_t iter)
 {
     int rv;
-    of_object_t *obj = (of_object_t *)_obj;
+    of_object_t *obj = iter.obj;
 
     if ((rv = of_list_next(list, obj)) < 0) {
         return rv;
@@ -105,9 +105,9 @@
  */
 
 int
-${cls}_append_bind(${cls}_t *list, ${e_cls}_t *obj)
+${cls}_append_bind(${cls}_t *list, of_list_iter_t iter)
 {
-    return of_list_append_bind(list, (of_object_t *)obj);
+    return of_list_append_bind(list, iter.obj);
 }
 
 /**
@@ -119,7 +119,7 @@
  */
 
 int
-${cls}_append(${cls}_t *list, ${e_cls}_t *obj)
+${cls}_append(${cls}_t *list, of_list_iter_t iter)
 {
-    return of_list_append(list, (of_object_t *)obj);
+    return of_list_append(list, iter.obj);
 }
diff --git a/c_gen/templates/loci_classes.h b/c_gen/templates/loci_classes.h
index c5147cb..86fe36b 100644
--- a/c_gen/templates/loci_classes.h
+++ b/c_gen/templates/loci_classes.h
@@ -36,6 +36,22 @@
 void ${uclass.name}_push_wire_types(of_object_t *obj);
 :: #endfor
 
+/*
+ * Transparent union used for list iteration
+ *
+ * This will be removed when all callers are converted to of_object_t.
+ */
+union of_list_iter_u {
+    of_object_t *obj;
+:: for uclass in loxi_globals.unified.classes:
+:: if uclass.virtual and not uclass.superclass:
+    union ${uclass.name}_u *${uclass.name};
+:: #endif
+:: #endfor
+} __attribute__ ((__transparent_union__));
+
+typedef union of_list_iter_u of_list_iter_t;
+
 ${legacy_code}
 
 #endif
diff --git a/c_gen/templates/locitest/test_utils.c b/c_gen/templates/locitest/test_utils.c
index 10a6b3d..d078a59 100644
--- a/c_gen/templates/locitest/test_utils.c
+++ b/c_gen/templates/locitest/test_utils.c
@@ -43,12 +43,8 @@
 test_has_outport(void)
 {
     of_list_action_t *list;
-    of_action_t elt;
-    of_action_set_dl_src_t *set_dl_src;
-    of_action_output_t *output;
-
-    set_dl_src = &elt.set_dl_src;
-    output = &elt.output;
+    of_object_t set_dl_src;
+    of_object_t output;
 
     list = of_list_action_new(OF_VERSION_1_0);
     TEST_ASSERT(list != NULL);
@@ -57,25 +53,25 @@
     TEST_ASSERT(!of_action_list_has_out_port(list, 1));
 
     /* Add some other action */
-    of_action_set_dl_src_init(set_dl_src, OF_VERSION_1_0, -1, 1);
-    TEST_OK(of_list_action_append_bind(list, (of_action_t *)set_dl_src));
+    of_action_set_dl_src_init(&set_dl_src, OF_VERSION_1_0, -1, 1);
+    TEST_OK(of_list_action_append_bind(list, &set_dl_src));
 
     TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
     TEST_ASSERT(!of_action_list_has_out_port(list, 1));
 
     /* Add port 2 */
-    of_action_output_init(output, OF_VERSION_1_0, -1, 1);
-    TEST_OK(of_list_action_append_bind(list, (of_action_t *)output));
-    of_action_output_port_set(output, 2);
+    of_action_output_init(&output, OF_VERSION_1_0, -1, 1);
+    TEST_OK(of_list_action_append_bind(list, &output));
+    of_action_output_port_set(&output, 2);
 
     TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
     TEST_ASSERT(!of_action_list_has_out_port(list, 1));
     TEST_ASSERT(of_action_list_has_out_port(list, 2));
 
     /* Add port 1 */
-    of_action_output_init(output, OF_VERSION_1_0, -1, 1);
-    TEST_OK(of_list_action_append_bind(list, (of_action_t *)output));
-    of_action_output_port_set(output, 1);
+    of_action_output_init(&output, OF_VERSION_1_0, -1, 1);
+    TEST_OK(of_list_action_append_bind(list, &output));
+    of_action_output_port_set(&output, 1);
 
     TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
     TEST_ASSERT(of_action_list_has_out_port(list, 1));
@@ -88,26 +84,26 @@
     TEST_ASSERT(list != NULL);
 
     /* Add port 2 */
-    of_action_output_init(output, OF_VERSION_1_0, -1, 1);
-    TEST_OK(of_list_action_append_bind(list, (of_action_t *)output));
-    of_action_output_port_set(output, 2);
+    of_action_output_init(&output, OF_VERSION_1_0, -1, 1);
+    TEST_OK(of_list_action_append_bind(list, &output));
+    of_action_output_port_set(&output, 2);
 
     TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
     TEST_ASSERT(!of_action_list_has_out_port(list, 1));
     TEST_ASSERT(of_action_list_has_out_port(list, 2));
 
     /* Add some other action */
-    of_action_set_dl_src_init(set_dl_src, OF_VERSION_1_0, -1, 1);
-    TEST_OK(of_list_action_append_bind(list, (of_action_t *)set_dl_src));
+    of_action_set_dl_src_init(&set_dl_src, OF_VERSION_1_0, -1, 1);
+    TEST_OK(of_list_action_append_bind(list, &set_dl_src));
 
     TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
     TEST_ASSERT(!of_action_list_has_out_port(list, 1));
     TEST_ASSERT(of_action_list_has_out_port(list, 2));
 
     /* Add port 1 */
-    of_action_output_init(output, OF_VERSION_1_0, -1, 1);
-    TEST_OK(of_list_action_append_bind(list, (of_action_t *)output));
-    of_action_output_port_set(output, 1);
+    of_action_output_init(&output, OF_VERSION_1_0, -1, 1);
+    TEST_OK(of_list_action_append_bind(list, &output));
+    of_action_output_port_set(&output, 1);
 
     TEST_ASSERT(of_action_list_has_out_port(list, OF_PORT_DEST_WILDCARD));
     TEST_ASSERT(of_action_list_has_out_port(list, 1));
diff --git a/c_gen/templates/locitest/test_validator.c b/c_gen/templates/locitest/test_validator.c
index a4b55eb..fde5cba 100644
--- a/c_gen/templates/locitest/test_validator.c
+++ b/c_gen/templates/locitest/test_validator.c
@@ -88,9 +88,9 @@
     of_message_t msg; 
     of_flow_modify_actions_bind(obj, &list);
     of_action_set_tp_dst_init(&element1, OF_VERSION_1_0, -1, 1);
-    of_list_action_append_bind(&list, (of_action_t *)&element1);
+    of_list_action_append_bind(&list, &element1);
     of_action_output_init(&element2, OF_VERSION_1_0, -1, 1);
-    of_list_action_append_bind(&list, (of_action_t *)&element2);
+    of_list_action_append_bind(&list, &element2);
     msg = OF_OBJECT_TO_MESSAGE(obj);
 
     TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == 0);
diff --git a/c_gen/templates/of_utils.c b/c_gen/templates/of_utils.c
index 373ad59..bddbc8d 100644
--- a/c_gen/templates/of_utils.c
+++ b/c_gen/templates/of_utils.c
@@ -54,7 +54,7 @@
 int
 of_action_list_has_out_port(of_list_action_t *actions, of_port_no_t outport)
 {
-    of_action_t elt;
+    of_object_t elt;
     of_action_output_t *output;
     int loop_rv;
     of_port_no_t port_no;
@@ -64,7 +64,7 @@
         return 1;
     }
 
-    output = &elt.output;
+    output = &elt;
     OF_LIST_ACTION_ITER(actions, &elt, loop_rv) {
         if (output->object_id == OF_ACTION_OUTPUT) {
             of_action_output_port_get(output, &port_no);
diff --git a/test_data/of10/flow_add.data b/test_data/of10/flow_add.data
index 60fd780..275a40e 100644
--- a/test_data/of10/flow_add.data
+++ b/test_data/of10/flow_add.data
@@ -117,19 +117,19 @@
     of_list_action_t actions;
     of_flow_add_actions_bind(obj, &actions);
     {
-        of_action_t action;
-        of_action_output_init(&action.output, OF_VERSION_1_0, -1, 1);
+        of_object_t action;
+        of_action_output_init(&action, OF_VERSION_1_0, -1, 1);
         of_list_action_append_bind(&actions, &action);
-        of_action_output_port_set(&action.output, OF_PORT_DEST_FLOOD);
+        of_action_output_port_set(&action, OF_PORT_DEST_FLOOD);
     }
     {
-        of_action_t action;
-        of_action_nicira_dec_ttl_init(&action.nicira_dec_ttl, OF_VERSION_1_0, -1, 1);
+        of_object_t action;
+        of_action_nicira_dec_ttl_init(&action, OF_VERSION_1_0, -1, 1);
         of_list_action_append_bind(&actions, &action);
     }
     {
-        of_action_t action;
-        of_action_bsn_set_tunnel_dst_init(&action.bsn_set_tunnel_dst, OF_VERSION_1_0, -1, 1);
+        of_object_t action;
+        of_action_bsn_set_tunnel_dst_init(&action, OF_VERSION_1_0, -1, 1);
         of_list_action_append_bind(&actions, &action);
     }
 }