28fc1e
From b86fec9baa9c2ee03b28cfc8dad95c41bf9acaad Mon Sep 17 00:00:00 2001
28fc1e
From: Flavio Leitner <fbl@redhat.com>
28fc1e
Date: Wed, 2 Oct 2013 02:40:09 -0300
28fc1e
Subject: [PATCH] util: use gcc builtins to better check array sizes
28fc1e
28fc1e
GCC provides two useful builtin functions that can help
28fc1e
to improve array size checking during compilation.
28fc1e
28fc1e
This patch contains no functional changes, but it makes
28fc1e
it easier to detect mistakes.
28fc1e
28fc1e
Signed-off-by: Flavio Leitner <fbl@redhat.com>
28fc1e
Signed-off-by: Ben Pfaff <blp@nicira.com>
28fc1e
---
28fc1e
 AUTHORS    |  1 +
28fc1e
 lib/util.h | 17 ++++++++++++++++-
28fc1e
 2 files changed, 17 insertions(+), 1 deletion(-)
28fc1e
28fc1e
diff --git a/AUTHORS b/AUTHORS
28fc1e
index af34bfe..7a919a2 100644
28fc1e
--- a/AUTHORS
28fc1e
+++ b/AUTHORS
28fc1e
@@ -32,6 +32,7 @@ Duffie Cooley           dcooley@nicira.com
28fc1e
 Ed Maste                emaste at freebsd.org
28fc1e
 Edward Tomasz NapieraƂa trasz@freebsd.org
28fc1e
 Ethan Jackson           ethan@nicira.com
28fc1e
+Flavio Leitner          fbl@redhat.com
28fc1e
 FUJITA Tomonori         fujita.tomonori@lab.ntt.co.jp
28fc1e
 Gaetano Catalli         gaetano.catalli@gmail.com
28fc1e
 Giuseppe Lettieri       g.lettieri@iet.unipi.it
28fc1e
diff --git a/lib/util.h b/lib/util.h
28fc1e
index 0db41be..a899065 100644
28fc1e
--- a/lib/util.h
28fc1e
+++ b/lib/util.h
28fc1e
@@ -87,8 +87,23 @@ void ovs_assert_failure(const char *, const char *, const char *) NO_RETURN;
28fc1e
 
28fc1e
 extern const char *program_name;
28fc1e
 
28fc1e
+#define __ARRAY_SIZE_NOCHECK(ARRAY) (sizeof(ARRAY) / sizeof((ARRAY)[0]))
28fc1e
+#ifdef __GNUC__
28fc1e
+/* return 0 for array types, 1 otherwise */
28fc1e
+#define __ARRAY_CHECK(ARRAY) 					\
28fc1e
+    !__builtin_types_compatible_p(typeof(ARRAY), typeof(&ARRAY[0]))
28fc1e
+
28fc1e
+/* compile-time fail if not array */
28fc1e
+#define __ARRAY_FAIL(ARRAY) (sizeof(char[-2*!__ARRAY_CHECK(ARRAY)]))
28fc1e
+#define __ARRAY_SIZE(ARRAY)					\
28fc1e
+    __builtin_choose_expr(__ARRAY_CHECK(ARRAY),			\
28fc1e
+        __ARRAY_SIZE_NOCHECK(ARRAY), __ARRAY_FAIL(ARRAY))
28fc1e
+#else
28fc1e
+#define __ARRAY_SIZE(ARRAY) __ARRAY_SIZE_NOCHECK(ARRAY)
28fc1e
+#endif
28fc1e
+
28fc1e
 /* Returns the number of elements in ARRAY. */
28fc1e
-#define ARRAY_SIZE(ARRAY) (sizeof ARRAY / sizeof *ARRAY)
28fc1e
+#define ARRAY_SIZE(ARRAY) __ARRAY_SIZE(ARRAY)
28fc1e
 
28fc1e
 /* Returns X / Y, rounding up.  X must be nonnegative to round correctly. */
28fc1e
 #define DIV_ROUND_UP(X, Y) (((X) + ((Y) - 1)) / (Y))
28fc1e
-- 
28fc1e
1.8.4.2
28fc1e