Opened 4 years ago

Closed 4 years ago

#198 closed defect (fixed)

Forward Declaration Leads to Bad Function Pointer Types

Reported by: ajbeach Owned by:
Priority: major Component: cfa-cc
Version: 1.0 Keywords:


So I have encountered a rather convoluted case where a combination of a circular dependency and a polymorphic function pointer leads to an error in the generated code. It appears that a concrete implementation is not getting forward declared. warning: 'struct _conc_object0' declared inside parameter list will not be visible outside of this definition or declaration
   12 |  void (*object_function)(object(T) *);

Here is the code to produce the error (the _vtable names are from how I discovered this but are not required, the virtual system seems to have nothing to do with this):

forall(otype T)
struct object_vtable;

forall(otype U)
struct object {
    object_vtable(U) * virtual_table;

forall(otype T)
struct object_vtable {
    void (*object_function)(object(T) *);

void func(object(int) * test) {}

object_vtable(int) _object_vtable_instance = { func };

The polymorphic variables currently have to be otypes because of #196. Once that bug is fixed they might be able to be changed to dtypes.

In object removing the virtual_table pointer or replacing it with a field that does not refer to object_vtable will cause the error to disappear. Whether the field is polymorphic or not doesn't matter, object_vtable(char) * produces the error but U * does not.

In object_vtable the function pointer field must refer to object and must be a function pointer. So the error remains with void (*f)(object(int) *) as long as the structure is polymorphic. But object(U) * x will compile just fine as will void (*f)(U *).

Also if the star is removed from the function pointer argument (and the same star on func) there is a burst of possibly related errors. If the initialization at the end of the examples is also changed this becomes a single warning on assignment of incompatible pointer types. Not sure if that is the same problem or not.

The initialization of _object_vtable_instance is required for the error to occur. It also happens if you use @= to initial the structure, it leads to an extra error: warning: initialization of 'void (*)(struct _conc_object0 *)' from incompatible pointer type 'void (*)(struct _conc_object0 *)' [-Wincompatible-pointer-types]
   19 | object_vtable(int) _object_vtable_instance @= { func };
     note: (near initialization for '_X23_object_vtable_instanceS13object_vtable_i__1._X15object_functionFv_PS6object_Y12__T_generic____1')

Change History (1)

comment:1 Changed 4 years ago by ajbeach

Resolution: fixed
Status: newclosed

I fixed this, hopefully. Also I poked around seeing which of the secondary errors I could still replicate. I could only reproduce one and that has a new ticket with the details for that error.

Note: See TracTickets for help on using tickets.