summaryrefslogtreecommitdiff
path: root/handy.h
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-03-04 14:22:27 +0000
committerDavid Mitchell <davem@iabyn.com>2015-03-04 14:37:22 +0000
commit88f9f1287d0ce35734ddb48ff7a8ee9f4b8efd3d (patch)
tree8178106993099427dcc04af5cc4bcf8d6ae72a33 /handy.h
parent661d43c45c6cc0d2dfbe99378a9c3fff68b6b571 (diff)
downloadperl-88f9f1287d0ce35734ddb48ff7a8ee9f4b8efd3d.tar.gz
further tweak MEM_WRAP_CHECK()
My recent mods to make it often constant-fold at time-time were generating Coverity warnings when the expression happened to equal (cond ? 1 : 1).
Diffstat (limited to 'handy.h')
-rw-r--r--handy.h27
1 files changed, 16 insertions, 11 deletions
diff --git a/handy.h b/handy.h
index 56261e6867..5414df1f5c 100644
--- a/handy.h
+++ b/handy.h
@@ -1890,21 +1890,26 @@ PoisonWith(0xEF) for catching access to freed memory.
# define _MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) \
(sizeof(t) > ((MEM_SIZE)1 << 8*(sizeof(MEM_SIZE) - sizeof(n))))
-/* this is written in a slightly odd way because for an expression like
- * cond && (n > expr)
- * even when cond constant-folds to false at compile-time, g++ insists
- * on emitting warnings about expr (e.g. "comparison is always false").
- * So rewrite it as
- * (cond ? n : 1) > expr
+/* This is written in a slightly odd way to avoid various spurious
+ * compiler warnings. We *want* to write
+ * _MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) && (n > const)
+ * but even when the LHS constant-folds to false at compile-time, g++
+ * insists on emitting warnings about the RHS (e.g. "comparison is always
+ * false"), so instead we write it as
*
- * We happen to know that (1 > expr) will always be false (unless someone
- * is doing something with a struct whose sizeof > MEM_SIZE_MAX/2), so
- * this is safe.
+ * (cond ? n : X) > const
+ *
+ * where X is a constant where X > const is always false.
+ * Choosing a value for X is tricky. If 0, some compilers will
+ * complain about 0 > const always being false; if 1, Coverity
+ * complains when n happens to be the constant value '1', that cond ? 1 : 1
+ * has the same value on both branches; so use const for X and hope
+ * that nothing else whines.
*/
# define _MEM_WRAP_WILL_WRAP(n,t) \
- ((MEM_SIZE)(_MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) ? n : 1) \
- > MEM_SIZE_MAX/sizeof(t))
+ ((_MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) ? (MEM_SIZE)(n) : \
+ MEM_SIZE_MAX/sizeof(t)) > MEM_SIZE_MAX/sizeof(t))
# define MEM_WRAP_CHECK(n,t) \
(void)(UNLIKELY(_MEM_WRAP_WILL_WRAP(n,t)) \