summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2017-01-24 14:04:44 -0800
committerH. Peter Anvin <hpa@zytor.com>2017-01-24 14:04:44 -0800
commita92a7dce5ed61d482c549abc3c1ef144025ec2ae (patch)
treebbfbb2523c6a3f3683a2ab451092c85928298f2e
parent75f2c1e131a7651a793abc8f59aea09b6226ce7d (diff)
downloadnasm-a92a7dce5ed61d482c549abc3c1ef144025ec2ae.tar.gz
nasm_delete(): ugly hack to make it side-effect-free
Use an ugly hack to make nasm_delete() side effect free. This assumes all pointers have the same internal NULL pointer representation as void *, however, we already assume zero-initialized memory will represent a NULL pointer, so hopefully this is okay on any platform we actually care about. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--include/nasmlib.h17
1 files changed, 14 insertions, 3 deletions
diff --git a/include/nasmlib.h b/include/nasmlib.h
index 218cf636..60c16df3 100644
--- a/include/nasmlib.h
+++ b/include/nasmlib.h
@@ -153,13 +153,24 @@ void nasm_free(void *);
char * safe_alloc nasm_strdup(const char *);
char * safe_alloc nasm_strndup(const char *, size_t);
+/* Assert the argument is a pointer without evaluating it */
+#define nasm_assert_pointer(p) ((void)sizeof(*(p)))
+
#define nasm_new(p) ((p) = nasm_zalloc(sizeof(*(p))))
#define nasm_newn(p,n) ((p) = nasm_calloc(sizeof(*(p)),(n)))
/*
- * Careful: nasm_delete() is not side-effect safe.
- * Any ideas how to fix that?
+ * This is broken on platforms where there are pointers which don't
+ * match void * in their internal layout. It unfortunately also
+ * loses any "const" part of the argument, although hopefully the
+ * compiler will warn in that case.
*/
-#define nasm_delete(p) do { nasm_free(p); (p) = NULL; } while (0)
+#define nasm_delete(p) \
+ do { \
+ void **_pp = (void **)&(p); \
+ nasm_assert_pointer(p); \
+ nasm_free(*_pp); \
+ *_pp = NULL; \
+ } while (0)
#define nasm_zero(p) (memset((p), 0, sizeof(*(p))))
/*