xserver: Branch 'master' - 3 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Sep 5 11:08:48 PDT 2012


 configure.ac            |    1 +
 include/dix-config.h.in |    3 +++
 include/list.h          |   21 +++++++++++++++++----
 test/list.c             |    4 ++--
 4 files changed, 23 insertions(+), 6 deletions(-)

New commits:
commit 856f80c8d7f22b979c72d9c70b70187df6004a03
Merge: 0db936a... b8ab93d...
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Sep 5 11:02:58 2012 -0700

    Merge remote-tracking branch 'jeremyhu/master'

commit b8ab93dfbc7f292b5bfe7e9113e1af824ccbd1a8
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue Aug 28 10:06:51 2012 -0700

    list: Use offsetof() and typeof() to determine member offsets within a structure
    
    Some compilers have difficulty with the previous implementation which
    relies on undefined behavior according to the C standard.  Using
    offsetof() from <stddef.h> (which most likely just uses
    __builtin_offsetof on modern compilers) allows us to accomplish this
    without ambiguity.
    
    This fix also requires support for typeof().  If your compiler does not
    support typeof(), then the old implementation will be used.  If you see
    failures in test/list, please try a more modern compiler.
    
    v2: Added fallback if typeof() is not present.
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/configure.ac b/configure.ac
index abfe727..ab89027 100644
--- a/configure.ac
+++ b/configure.ac
@@ -137,6 +137,7 @@ AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h fnmatch.h
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
+AC_C_TYPEOF
 AC_C_BIGENDIAN([ENDIAN="X_BIG_ENDIAN"], [ENDIAN="X_LITTLE_ENDIAN"])
 
 AC_CHECK_SIZEOF([unsigned long])
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index 77681a9..578f249 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -423,6 +423,9 @@
 /* Define to 64-bit byteswap macro */
 #undef bswap_64
 
+/* Define to 1 if typeof works with your compiler. */
+#undef HAVE_TYPEOF
+
 /* The compiler supported TLS storage class, prefering initial-exec if tls_model is supported */
 #undef TLS
 
diff --git a/include/list.h b/include/list.h
index d54a207..2d48a86 100644
--- a/include/list.h
+++ b/include/list.h
@@ -26,6 +26,8 @@
 #ifndef _XORG_LIST_H_
 #define _XORG_LIST_H_
 
+#include <stddef.h> /* offsetof() */
+
 /**
  * @file Classic doubly-link circular list implementation.
  * For real usage examples of the linked list, see the file test/list.c
@@ -232,7 +234,7 @@ xorg_list_is_empty(struct xorg_list *head)
  */
 #ifndef container_of
 #define container_of(ptr, type, member) \
-    (type *)((char *)(ptr) - (char *) &((type *)0)->member)
+    (type *)((char *)(ptr) - offsetof(type, member))
 #endif
 
 /**
@@ -271,9 +273,20 @@ xorg_list_is_empty(struct xorg_list *head)
 #define xorg_list_last_entry(ptr, type, member) \
     xorg_list_entry((ptr)->prev, type, member)
 
-#define __container_of(ptr, sample, member)				\
-    (void *)((char *)(ptr)						\
-	     - ((char *)&(sample)->member - (char *)(sample)))
+#ifdef HAVE_TYPEOF
+#define __container_of(ptr, sample, member)			\
+    container_of(ptr, typeof(*sample), member)
+#else
+/* This implementation of __container_of has undefined behavior according
+ * to the C standard, but it works in many cases.  If your compiler doesn't
+ * support typeof() and fails with this implementation, please try a newer
+ * compiler.
+ */
+#define __container_of(ptr, sample, member)                            \
+    (void *)((char *)(ptr)                                             \
+            - ((char *)&(sample)->member - (char *)(sample)))
+#endif
+
 /**
  * Loop through the list given by head and set pos to struct in the list.
  *
commit c75c947b6e9bc725821b28835f3667c4aabef9ee
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Tue Aug 28 12:43:55 2012 -0700

    test/list: Fix test_xorg_list_del test
    
    We never use child[2], so it's state is undefined.
    
    This issue seems to have existed since the test was first
    written: 92788e677be79bd04e5ef140f4ced50ad8b1bf8e
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/list.c b/test/list.c
index 82d2327..f9f54ee 100644
--- a/test/list.c
+++ b/test/list.c
@@ -137,7 +137,7 @@ static void
 test_xorg_list_del(void)
 {
     struct parent parent = { 0 };
-    struct child child[3];
+    struct child child[2];
     struct child *c;
 
     xorg_list_init(&parent.children);
@@ -178,8 +178,8 @@ test_xorg_list_del(void)
     xorg_list_add(&child[0].node, &parent.children);
     xorg_list_del(&parent.children);
     assert(xorg_list_is_empty(&parent.children));
+    assert(!xorg_list_is_empty(&child[0].node));
     assert(!xorg_list_is_empty(&child[1].node));
-    assert(!xorg_list_is_empty(&child[2].node));
 }
 
 static void


More information about the xorg-commit mailing list