The _auto_-macro used in cert.c and tls.c uses a GCC extension that allows for nested functions. This is not supported by other compilers, including clang. Compiling ell with these compilers will result error messages such as: ../ell-0.44/ell/tls.c:1895:2: error: function definition is not allowed here _auto_(l_certchain_free) struct l_certchain *certchain = NULL; ^ ../ell-0.44/ell/useful.h:71:2: note: expanded from macro '_auto_' _AUTODESTRUCT(__COUNTER__, func) ^ ../ell-0.44/ell/useful.h:68:2: note: expanded from macro '_AUTODESTRUCT' __AUTODESTRUCT(var, func) ^ ../ell-0.44/ell/useful.h:64:2: note: expanded from macro '__AUTODESTRUCT' { func(*(void **) ptr); } \ ^ ../ell-0.44/ell/tls.c:1895:2: error: use of undeclared identifier 'cleanup_0' ../ell-0.44/ell/useful.h:71:2: note: expanded from macro '_auto_' _AUTODESTRUCT(__COUNTER__, func) ^ ../ell-0.44/ell/useful.h:68:2: note: expanded from macro '_AUTODESTRUCT' __AUTODESTRUCT(var, func) ^ ../ell-0.44/ell/useful.h:65:23: note: expanded from macro '__AUTODESTRUCT' __attribute((cleanup(cleanup_ ## var))) ^ This patch will removes the _auto_ macro and implement its functionality manually in the two locations it is used. It does not appear to be possible to replace this macro with a more compatible alternative that does not involve C++. Signed-off-by: Charlotte Delenk --- ell/cert.c | 6 +++++- ell/tls.c | 6 +++++- ell/useful.h | 11 ----------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/ell/cert.c b/ell/cert.c index 141ea1c..13a89e0 100644 --- a/ell/cert.c +++ b/ell/cert.c @@ -446,12 +446,16 @@ static struct l_key *cert_try_link(struct l_cert *cert, struct l_keyring *ring) return false; \ } while (0) +static void cleanup_keyring(void * ptr) { + l_keyring_free(*(void **)ptr); +} + LIB_EXPORT bool l_certchain_verify(struct l_certchain *chain, struct l_queue *ca_certs, const char **error) { struct l_keyring *ca_ring = NULL; - _auto_(l_keyring_free) struct l_keyring *verify_ring = NULL; + __attribute__((cleanup(cleanup_keyring))) struct l_keyring *verify_ring = NULL; struct l_cert *cert; struct l_key *prev_key = NULL; int verified = 0; diff --git a/ell/tls.c b/ell/tls.c index c246f1f..1d0e91d 100644 --- a/ell/tls.c +++ b/ell/tls.c @@ -1888,11 +1888,15 @@ decode_error: "ServerHello decode error"); } +static void cleanup_certchain(void * ptr) { + l_certchain_free(*(void **)ptr); +} + static void tls_handle_certificate(struct l_tls *tls, const uint8_t *buf, size_t len) { size_t total; - _auto_(l_certchain_free) struct l_certchain *certchain = NULL; + __attribute__((cleanup(cleanup_certchain))) struct l_certchain *certchain = NULL; struct l_cert *leaf; size_t der_len; const uint8_t *der; diff --git a/ell/useful.h b/ell/useful.h index b4783ce..cd7ec0f 100644 --- a/ell/useful.h +++ b/ell/useful.h @@ -59,17 +59,6 @@ static inline unsigned char bit_field(const unsigned char oct, _x / _d; \ }) -#define __AUTODESTRUCT(var, func) \ - void cleanup_ ## var(void *ptr) \ - { func(*(void **) ptr); } \ - __attribute((cleanup(cleanup_ ## var))) - -#define _AUTODESTRUCT(var, func) \ - __AUTODESTRUCT(var, func) - -#define _auto_(func) \ - _AUTODESTRUCT(__COUNTER__, func) - /* * Trick the compiler into thinking that var might be changed somehow by * the asm -- 2.33.0