From 246ea3f94d5e4c62078bcbd44a197ff93f590ef0 Mon Sep 17 00:00:00 2001 From: leitner Date: Thu, 20 Mar 2025 10:57:15 +0000 Subject: [PATCH] try to unify ownership over gcc and clang --- buffer.h | 14 +++++++------- compiler.h | 32 +++++++++++++++++++++++--------- iob.h | 13 ++++++------- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/buffer.h b/buffer.h index 51c28f8..04c4624 100644 --- a/buffer.h +++ b/buffer.h @@ -35,25 +35,25 @@ typedef struct buffer { /* Initialize a buffer with an existing memory area, which the buffer * will NOT take ownership of (i.e. won't free the memory when it's done) */ __bufout(4,5) -att_holds(4) +att_holds(malloc,4) void buffer_init(buffer* b, ssize_t (*op)(), int fd, char* y, size_t ylen); /* Initialize a buffer with an existing memory area, which the buffer * WILL take ownership of (it will call free() on it when it's done) */ __bufout(4,5) -att_free(4) +att_free(malloc,4) void buffer_init_free(buffer* b,ssize_t (*op)(),int fd,char* y,size_t ylen); /* Call buffer_init with op=read(), return 0. * If fd==-1, return -1 instead, leaving b untouched. */ __bufout(3,4) -att_holds(3) +att_holds(malloc,3) int buffer_init_read(buffer* b, int fd, char* y, size_t ylen); /* Call buffer_init with op=write(), return 0. * If fd==-1, return -1 instead, leaving b untouched. */ __bufout(3,4) -att_holds(3) +att_holds(malloc,3) int buffer_init_write(buffer* b, int fd, char* y, size_t ylen); /* Will allocate a buffer of size ylen and then call @@ -77,19 +77,19 @@ int buffer_init_write_allocbuf(buffer* b, int fd, size_t ylen); * actually attempt to read from any actual file. * Does not take ownership. Useful for testing. */ __bufin(2,3) -att_holds(2) +att_holds(malloc,2) void buffer_init_staticcontents(buffer* b,char* y,size_t ylen); /* Same but the buffer takes ownership of the static buffer and frees it * in buffer_close. */ __bufin(2,3) -att_free(2) +att_free(malloc,2) void buffer_init_staticcontents_free(buffer* b,char* y,size_t ylen); /* Set buffer->deinit to this if you want buffer_close() to call free() on * the associated memory buffer */ -att_free(1) +att_free(malloc,1) void buffer_free(void* buf); /* Set buffer->deinit to this if you want buffer_close() to call munmap() on diff --git a/compiler.h b/compiler.h index e2eb55a..1f09c3e 100644 --- a/compiler.h +++ b/compiler.h @@ -99,8 +99,8 @@ #define att_alloc(x) __attribute__((alloc_size(x))) #define att_calloc(x,y) __attribute__((alloc_size(x,y))) #else -#define att_alloc -#define att_calloc +#define att_alloc(x) +#define att_calloc(x,y) #endif // Function attributes. @@ -146,7 +146,7 @@ // abort compilation on error. #if GCC_VERSION_ATLEAST(4, 3) #define att_warn(message) __attribute__((__warning__(message))) -#define att_error(message) __attribute__((__warning__(message))) +#define att_error(message) __attribute__((__error__(message))) #else #define att_warn(message) #define att_error(message) @@ -215,14 +215,28 @@ #endif // !defined(__GNUC__) #endif // !defined(__dietlibc__ +// in order to cover both clang and gcc, we'll need a convention +// att_new(myfree,1) void* mymalloc(size_t n); +// here myfree is the name of the free function, and 1 means you pass +// the pointer you want to free as first argument to myfree. +// att_free(myfree,1) void myfree(void* freeme); +// same meaning of id and idx here +// att_holds(myfree,2) int add_to_list_and_give_ownership(list* l,void* ptr); +// myfree is the name of the free function so that clang can link them +// and 2 is the index of the pointer whose ownership is transferred +// use "malloc" as id to indicate regular malloc'ed pointers #if __has_attribute(ownership_takes) -#define att_new __attribute__((ownership_returns(malloc))) -#define att_free(idx) __attribute__((ownership_takes(malloc, idx))) -#define att_holds(idx) __attribute__((ownership_holds(malloc, idx))) +#define att_new(id,idx) __attribute__((ownership_returns(id))) +#define att_free(id,idx) __attribute__((ownership_takes(id, idx))) +#define att_holds(id,idx) __attribute__((ownership_holds(id, idx))) +#elif __GNUC__ >= 11 +#define att_new(id,idx) __attribute__((malloc(id,idx))) +#define att_free(id,idx) +#define att_holds(id,idx) #else -#define att_new -#define att_free(idx) -#define att_holds(idx) +#define att_new(id,idx) +#define att_free(id,idx) +#define att_holds(id,idx) #endif #if __GNUC__ >= 11 diff --git a/iob.h b/iob.h index aba88a8..5c78629 100644 --- a/iob.h +++ b/iob.h @@ -59,24 +59,23 @@ att_warn_unused_result int iob_init_autofree(io_batch* b,size_t hint_entries); /* malloc and initialize an io_batch */ -att_free_with(iob_free,1) -att_new +att_new(iob_free,1) io_batch* iob_new(size_t hint_entries); /* malloc and initialize an io_batch that auto-frees entries as soon as * iob_send/iob_write have written them */ -att_free_with(iob_free,1) +att_new(iob_free,1) io_batch* iob_new_autofree(size_t hint_entries); /* queue buffer in io_batch */ att_readn(2,3) -att_holds(1) +att_holds(malloc,2) int iob_addbuf(io_batch* b,const void* buf,uint64 n); /* queue buffer in io_batch, and give ownership to batch. */ /* the io_batch functions will take care of freeing it. */ att_readn(2,3) -att_free(1) +att_free(malloc,2) int iob_addbuf_free(io_batch* b,const void* buf,uint64 n); /* queue mmapped memory reagion in io_batch, and give ownership to batch. */ @@ -86,13 +85,13 @@ int iob_addbuf_munmap(io_batch* b,const void* buf,uint64 n); /* queue asciiz string in io_batch. */ att_read(2) -att_holds(2) +att_holds(malloc,2) int iob_adds(io_batch* b,const char* s); /* queue asciiz string in io_batch, and give ownership to batch. */ /* the io_batch functions will take care of freeing it. */ att_read(2) -att_free(2) +att_free(malloc,2) int iob_adds_free(io_batch* b,const char* s); /* queue file contents in io_batch. */