Skip to content

Commit

Permalink
ubsan: fix "call to function through pointer to incorrect function ty…
Browse files Browse the repository at this point in the history
…pe" (#4598)

ubsan doesn't like call's through function pointers of incorrect function
types. This is used in both hash/list stuff along with in genprim. This
commit fixes things to make ubsan happy.

Makes ubsan runtime errors such as the following go away:

`runtime error: call to function flag_free through pointer to incorrect function type 'void (*)(void *)'`
  • Loading branch information
dipinhora authored Feb 6, 2025
1 parent b150f78 commit c96929b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 31 deletions.
12 changes: 3 additions & 9 deletions src/libponyc/codegen/genprim.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@
(void)c_m;

#define BOX_FUNCTION(gen, gen_data) \
box_function(c, (generate_box_fn)gen, gen_data);
gen(c, gen_data, TK_BOX); \
gen(c, gen_data, TK_REF); \
gen(c, gen_data, TK_VAL);

#define GENERIC_FUNCTION(name, gen) \
generic_function(c, t, stringtab(name), gen);

typedef void (*generate_box_fn)(compile_t*, void*, token_id);
typedef void (*generate_gen_fn)(compile_t*, reach_type_t*, reach_method_t*);

static void start_function(compile_t* c, reach_type_t* t, reach_method_t* m,
Expand All @@ -46,13 +47,6 @@ static void start_function(compile_t* c, reach_type_t* t, reach_method_t* m,
codegen_startfun(c, c_m->func, NULL, NULL, NULL, false);
}

static void box_function(compile_t* c, generate_box_fn gen, void* gen_data)
{
gen(c, gen_data, TK_BOX);
gen(c, gen_data, TK_REF);
gen(c, gen_data, TK_VAL);
}

static void generic_function(compile_t* c, reach_type_t* t, const char* name,
generate_gen_fn gen)
{
Expand Down
31 changes: 19 additions & 12 deletions src/libponyrt/ds/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,43 +160,50 @@ void ponyint_hashmap_deserialise(pony_ctx_t* ctx, void* object,
typedef bool (*name##_cmp_fn)(type* a, type* b); \
typedef void (*name##_free_fn)(type* a); \
\
static void name##_freef(void* data) \
{ \
name##_free_fn freef = free_elem; \
freef((type*)data); \
} \
static bool name##_cmpf(void* a, void* b) \
{ \
name##_cmp_fn cmpf = cmp; \
return cmpf((type*)a, (type*)b); \
} \
void name##_init(name_t* map, size_t size) \
{ \
ponyint_hashmap_init((hashmap_t*)map, size); \
} \
void name##_destroy(name_t* map) \
{ \
name##_free_fn freef = free_elem; \
ponyint_hashmap_destroy((hashmap_t*)map, (free_fn)freef); \
free_fn free_f = NULL; \
if (free_elem != NULL) \
free_f = name##_freef; \
ponyint_hashmap_destroy((hashmap_t*)map, free_f); \
} \
void name##_optimize(name_t* map) \
{ \
name##_cmp_fn cmpf = cmp; \
return ponyint_hashmap_optimize((hashmap_t*)map, (cmp_fn)cmpf); \
return ponyint_hashmap_optimize((hashmap_t*)map, name##_cmpf); \
} \
type* name##_get(name_t* map, type* key, size_t* index) \
{ \
name##_cmp_fn cmpf = cmp; \
return (type*)ponyint_hashmap_get((hashmap_t*)map, (void*)key, \
hash(key), (cmp_fn)cmpf, index); \
hash(key), name##_cmpf, index); \
} \
type* name##_put(name_t* map, type* entry) \
{ \
name##_cmp_fn cmpf = cmp; \
return (type*)ponyint_hashmap_put((hashmap_t*)map, (void*)entry, \
hash(entry), (cmp_fn)cmpf); \
hash(entry), name##_cmpf); \
} \
void name##_putindex(name_t* map, type* entry, size_t index) \
{ \
name##_cmp_fn cmpf = cmp; \
ponyint_hashmap_putindex((hashmap_t*)map, (void*)entry, \
hash(entry), (cmp_fn)cmpf, index); \
hash(entry), name##_cmpf, index); \
} \
type* name##_remove(name_t* map, type* entry) \
{ \
name##_cmp_fn cmpf = cmp; \
return (type*)ponyint_hashmap_remove((hashmap_t*) map, (void*)entry, \
hash(entry), (cmp_fn)cmpf); \
hash(entry), name##_cmpf); \
} \
void name##_removeindex(name_t* map, size_t index) \
{ \
Expand Down
28 changes: 18 additions & 10 deletions src/libponyrt/ds/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ void ponyint_list_deserialise(pony_ctx_t* ctx, void* object,
#define DEFINE_LIST(name, name_t, elem, cmpf, freef) \
struct name_t {list_t contents;}; \
\
static void name##_freef(void* data) \
{ \
name##_free_fn freefn = freef; \
freefn((elem*)data); \
} \
static bool name##_cmpf(void* a, void* b) \
{ \
name##_cmp_fn cmpfn = cmpf; \
return cmpfn((elem*)a, (elem*)b); \
} \
name_t* name##_pop(name_t* list, elem** data) \
{ \
return (name_t*)ponyint_list_pop((list_t*)list, (void**)data); \
Expand All @@ -109,23 +119,19 @@ void ponyint_list_deserialise(pony_ctx_t* ctx, void* object,
} \
elem* name##_find(name_t* list, elem* data) \
{ \
name##_cmp_fn cmp = cmpf; \
return (elem*)ponyint_list_find((list_t*)list, (cmp_fn)cmp, (void*)data); \
return (elem*)ponyint_list_find((list_t*)list, name##_cmpf, (void*)data); \
} \
ssize_t name##_findindex(name_t* list, elem* data) \
{ \
name##_cmp_fn cmp = cmpf; \
return ponyint_list_findindex((list_t*)list, (cmp_fn)cmp, (void*)data); \
return ponyint_list_findindex((list_t*)list, name##_cmpf, (void*)data); \
} \
bool name##_subset(name_t* a, name_t* b) \
{ \
name##_cmp_fn cmp = cmpf; \
return ponyint_list_subset((list_t*)a, (list_t*)b, (cmp_fn)cmp); \
return ponyint_list_subset((list_t*)a, (list_t*)b, name##_cmpf); \
} \
bool name##_equals(name_t* a, name_t* b) \
{ \
name##_cmp_fn cmp = cmpf; \
return ponyint_list_equals((list_t*)a, (list_t*)b, (cmp_fn)cmp); \
return ponyint_list_equals((list_t*)a, (list_t*)b, name##_cmpf); \
} \
name_t* name##_map(name_t* list, name##_map_fn f, void* arg) \
{ \
Expand All @@ -141,8 +147,10 @@ void ponyint_list_deserialise(pony_ctx_t* ctx, void* object,
} \
void name##_free(name_t* list) \
{ \
name##_free_fn free = freef; \
ponyint_list_free((list_t*)list, (free_fn)free); \
free_fn free_fn = NULL; \
if (freef != NULL) \
free_fn = name##_freef; \
ponyint_list_free((list_t*)list, free_fn); \
} \

#define DEFINE_LIST_SERIALISE(name, name_t, elem, cmpf, freef, elem_type) \
Expand Down

0 comments on commit c96929b

Please sign in to comment.