/* libmisc/tests/test_vcall.c - Tests for * * Copyright (C) 2024 Luke T. Shumaker * SPDX-License-Identifier: AGPL-3.0-or-later */ #include #include #include "test.h" /******************************************************************************/ struct frobber_vtable; typedef struct { struct frobber_vtable *vtable; } implements_frobber; struct frobber_vtable { int (*frob)(implements_frobber *); int (*frob1)(implements_frobber *, int); void (*frob0)(implements_frobber *); }; /******************************************************************************/ struct myclass { int a; implements_frobber; }; static_assert(offsetof(struct myclass, implements_frobber) != 0); static int myclass_frob(implements_frobber *_self) { struct myclass *self = VCALL_SELF(struct myclass, implements_frobber, _self); test_assert(self); test_assert((void*)self != (void*)_self); return self->a; } static int myclass_frob1(implements_frobber *_self, int arg) { struct myclass *self = VCALL_SELF(struct myclass, implements_frobber, _self); test_assert(self); test_assert((void*)self != (void*)_self); return arg; } static void myclass_frob0(implements_frobber *_self) { struct myclass *self = VCALL_SELF(struct myclass, implements_frobber, _self); test_assert(self); test_assert((void*)self != (void*)_self); } struct frobber_vtable myclass_vtable = { .frob = myclass_frob, .frob1 = myclass_frob1, .frob0 = myclass_frob0, }; /******************************************************************************/ #define MAGIC1 909837 #define MAGIC2 657441 int main() { struct myclass obj = { .implements_frobber = { .vtable = &myclass_vtable }, .a = MAGIC1, }; test_assert(VCALL(&obj, frob) == MAGIC1); test_assert(VCALL(&obj, frob1, MAGIC2) == MAGIC2); VCALL(&obj, frob0); return 0; }