more compiler attribute annotations

This commit is contained in:
leitner
2025-03-17 12:59:03 +00:00
parent e680441fa7
commit 144912a41d
4 changed files with 74 additions and 44 deletions

2
cdb.h
View File

@@ -47,7 +47,7 @@ int cdb_firstkey(struct cdb * restrict c,uint32 * restrict kpos);
att_write(1)
int cdb_nextkey(struct cdb * restrict c,uint32 * restrict kpos);
__bufin(2,3)
__bufin_ornull(2,3)
int cdb_successor(struct cdb * restrict c, const unsigned char * restrict buf, size_t len);
#define cdb_datapos(c) ((c)->dpos)

View File

@@ -1,5 +1,5 @@
#ifndef LIBOWFAT_ATTRIBUTES_H
#define LIBOWFAT_ATTRIBUTES_H
#ifndef LIBOWFAT_COMPILER_H
#define LIBOWFAT_COMPILER_H
// This is here so you can use inline with older gcc versions
#if __GNUC__ && (__STDC_VERSION__ < 199901L)
@@ -160,55 +160,68 @@
#ifndef __dietlibc__
#if defined(__GNUC__)
#if __has_attribute(null_terminated_string_arg)
#if !__has_attribute(null_terminated_string_arg)
#define null_terminated_string_arg(a)
#endif
#if !__has_attribute(nonnull_if_nonzero)
#define nonnull_if_nonzero(idx,szidx)
#endif
#if __has_attribute(access)
#define __access(a,b) access(a,b)
#define __access3(a,b,c) access(a,b,c)
#else
#define __access(a,b)
#define __access3(a,b,c)
#endif
// Function arguments.
// __strin: Argument idx (counted left to right from 1) is a non-NULL string the function reads
#define __strin(idx) __attribute__((nonnull(idx),access(read_only,idx),null_terminated_string_arg(idx)))
#define __strin(idx) __attribute__((nonnull(idx),__access(read_only,idx),null_terminated_string_arg(idx)))
// __strnin: Argument idx (counted left to right from 1) is a non-NULL string the function reads, length limit in array elements given in the szidx'th argument
#define __strnin(idx,szidx) __attribute__((nonnull(idx),access(read_only,idx,szidx),null_terminated_string_arg(idx)))
#define __strnin(idx,szidx) __attribute__((nonnull(idx),__access3(read_only,idx,szidx)))
// __strnin_ornull: like _strnin but if length is 0, ptr can be NULL
#define __strnin_ornull(idx,szidx) __attribute__((nonnull_if_nonzero(idx,szidx),__access3(read_only,idx,szidx)))
// __bufin: Argument idx (counted left to right from 1) is a non-NULL buffer the function reads from, length limit in array elements given in the szidx'th argument
#define __bufin(bufidx,szidx) __attribute__((nonnull(bufidx),access(read_only,bufidx,szidx)))
#define __bufin(bufidx,szidx) __attribute__((nonnull(bufidx),__access3(read_only,bufidx,szidx)))
// __bufin_ornull: like __bufin but if length is 0, ptr can be NULL
#define __bufin_ornull(bufidx,szidx) __attribute__((nonnull_if_nonzero(bufidx,szidx),__access3(read_only,bufidx,szidx)))
// __strout: Argument idx (counted left to right from 1) is a non-NULL string the function writes
// Currently we can't tell the compiler that the output will be 0-terminated.
#define __strout(idx) __attribute__((nonnull(idx),access(write_only,idx)))
#define __strout(idx) __attribute__((nonnull(idx),__access(write_only,idx)))
// __strnout: Argument idx (counted left to right from 1) is a non-NULL string the function writes, buffer size given in szidx'th function argument (in array elements, not necessarily bytes)
// Currently we can't tell the compiler that the output will be 0-terminated.
#define __strnout(idx,szidx) __attribute__((nonnull(idx),access(write_only,idx,szidx)))
#define __strnout(idx,szidx) __attribute__((nonnull(idx),__access3(write_only,idx,szidx)))
// __bufout: Argument idx (counted left to right from 1) is a non-NULL buffer the function writes, buffer size given in szidx'th function argument (in array elements, not necessarily bytes)
#define __bufout(bufidx,szidx) __attribute__((nonnull(bufidx),access(write_only,bufidx,szidx)))
#define __bufout(bufidx,szidx) __attribute__((nonnull(bufidx),__access3(write_only,bufidx,szidx)))
// __strinout: Argument idx (counted left to right from 1) is a non-NULL string the function reads and writes
// Currently we can't tell the compiler that the output will be 0-terminated.
#define __strinout(idx) __attribute__((nonnull(idx),access(read_write,idx),null_terminated_string_arg(idx)))
#define __strinout(idx) __attribute__((nonnull(idx),__access(read_write,idx),null_terminated_string_arg(idx)))
// __strninout: Argument idx (counted left to right from 1) is a non-NULL string the function reads and writes, buffer size in szidx'th function argument (in array elements, not necessarily bytes)
// Currently we can't tell the compiler that the output will be 0-terminated.
#define __strninout(idx,szidx) __attribute__((nonnull(idx),access(read_write,idx,szidx),null_terminated_string_arg(idx)))
#define __strninout(idx,szidx) __attribute__((nonnull(idx),__access3(read_write,idx,szidx)))
// __bufinout: Argument idx (counted left to right from 1) is a non-NULL buffer the function reads and writes, buffer size in szidx'th function argument (in array elements, not necessarily bytes)
#define __bufinout(bufidx,szidx) __attribute__((nonnull(bufidx),access(read_write,bufidx,szidx)))
#elif GCC_VERSION_ATLEAST(10, 0)
#define __strin(idx) __attribute__((nonnull(idx),access(read_only,idx)))
#define __strnin(idx,szidx) __attribute__((nonnull(idx),access(read_only,idx,szidx)))
#define __bufin(bufidx,szidx) __attribute__((nonnull(bufidx),access(read_only,bufidx,szidx)))
#define __strout(idx) __attribute__((nonnull(idx),access(write_only,idx)))
#define __strnout(idx,szidx) __attribute__((nonnull(idx),access(write_only,idx,szidx)))
#define __bufout(bufidx,szidx) __attribute__((nonnull(bufidx),access(write_only,bufidx,szidx)))
#define __strinout(idx) __attribute__((nonnull(idx),access(read_write,idx)))
#define __strninout(idx,szidx) __attribute__((nonnull(idx),access(read_write,idx,szidx)))
#define __bufinout(bufidx,szidx) __attribute__((nonnull(bufidx),access(read_write,bufidx,szidx)))
#define __bufinout(bufidx,szidx) __attribute__((nonnull(bufidx),__access3(read_write,bufidx,szidx)))
#elif GCC_VERSION_ATLEAST(3, 3)
#define __strin(idx) __attribute__((nonnull(idx)))
#define __strnin(idx,szidx) __attribute__((nonnull(idx)))
#define __bufin(bufidx,szidx) __attribute__((nonnull(bufidx)))
#define __strout(idx) __attribute__((nonnull(idx)))
#define __strnout(idx,szidx) __attribute__((nonnull(idx)))
#define __bufout(bufidx,szidx) __attribute__((nonnull(bufidx)))
#define __strinout(idx) __attribute__((nonnull(idx)))
#define __strninout(idx,szidx) __attribute__((nonnull(idx)))
#define __bufinout(bufidx,szidx) __attribute__((nonnull(bufidx)))
#endif
#endif // !defined(__GNUC__)
#endif // !defined(__dietlibc__
#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)))
#else
#define att_new
#define att_free(idx)
#define att_holds(idx)
#endif
#if __GNUC__ >= 11
#define att_free_with(func,argpos) __attribute__((malloc(func,argpos)))
#else
#define att_free_with(func,argpos) __attribute__((malloc))
#endif
#endif

4
fmt.h
View File

@@ -242,11 +242,11 @@ size_t fmt_pb_double(char* dest,size_t fieldno,double d) noexcept;
att_write(1)
size_t fmt_pb_float(char* dest,size_t fieldno,float f) noexcept;
att_writen(1,4)
att_write(1) att_readn(3,4)
size_t fmt_pb_string(char* dest,size_t fieldno,const char* s,size_t l) noexcept;
/* fmt_netstring can return 0 if (src,len) is clearly invalid */
att_writen(1,3)
att_write(1) att_readn(2,3)
size_t fmt_netstring(char* dest,const char* src,size_t len) noexcept;
/* Marshaling helper functions.

29
iob.h
View File

@@ -39,25 +39,44 @@ typedef struct io_batch {
/* Initialize an io_batch. Return 0 on success, -1 on malloc failure for
* embedded array */
att_nonnull((1))
att_warn_unused_result
int iob_init(io_batch* b,size_t hint_entries);
/* iob_reset closes files and frees buffer in the io_batch, and the
* array with the buffer, but not the batch itself (in case it's a local
* variable and not malloced) */
void iob_reset(io_batch* b);
/* iob_free does iob_reset but also frees the batch itself */
void iob_free(io_batch* b);
/* initialize an io_batch that auto-frees entries as soon as
* iob_send/iob_write have written them. Return 0 on success, -1 on
* malloc failure for embedded array */
att_nonnull((1))
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
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)
io_batch* iob_new_autofree(size_t hint_entries);
/* queue buffer in io_batch */
att_readn(2,3)
att_holds(1)
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)
int iob_addbuf_free(io_batch* b,const void* buf,uint64 n);
/* queue mmapped memory reagion in io_batch, and give ownership to batch. */
@@ -67,11 +86,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)
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)
int iob_adds_free(io_batch* b,const char* s);
/* queue file contents in io_batch. */
@@ -93,13 +114,9 @@ int64 iob_write(int64 s,io_batch* b,io_write_callback cb);
/* same as iob_write if the TLS library also has a sendfile function */
int64 iob_write2(int64 s,io_batch* b,io_write_callback cb,io_sendfile_callback sfcb);
/* iob_reset closes files and frees buffer in the io_batch, and the
* array with the buffer, but not the batch itself (in case it's a local
* variable and not malloced) */
void iob_reset(io_batch* b);
/* iob_free does iob_reset but also frees the batch itself */
void iob_free(io_batch* b);
void iob_prefetch(io_batch* b,uint64 bytes);
att_pure
uint64 iob_bytesleft(const io_batch* b);
#ifdef __cplusplus