[mutter] Avoid triggering strict-aliasing checks when iterating preferences



commit 9915a18810ef5f04d9a111a4aa2269338c6bf1ef
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Tue Apr 13 14:40:31 2010 -0400

    Avoid triggering strict-aliasing checks when iterating preferences
    
    Rewrite the code to iterate generically over Meta*Preference
    arrays to avoid running into GCC's strict-aliasing warnings.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=615672

 src/core/prefs.c |   72 ++++++++++++++++++++++++++++-------------------------
 1 files changed, 38 insertions(+), 34 deletions(-)
---
diff --git a/src/core/prefs.c b/src/core/prefs.c
index 8ca11c8..7252093 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -232,15 +232,9 @@ static GConfEnumStringPair symtab_titlebar_action[] =
   };
 
 /*
- * This structure represents the common parts at the front of all
- * the preferences structures; there are some additional places
- * it could be used in addition to where it is currently.
+ * Note that 'gchar *key' is the first element of all these structures;
+ * we count on that below in key_is_used and do_override.
  */
-typedef struct
-{
-  gchar *key;
-  MetaPreference pref;
-} MetaGenericPreference;
 
 /*
  * The details of one preference which is constrained to be
@@ -1115,41 +1109,51 @@ meta_prefs_init (void)
   init_workspace_names ();
 }
 
+/* This count on the key being the first element of the
+ * preference structure */
 static gboolean
-key_is_used (MetaGenericPreference *prefs,
-             size_t                 pref_size,
-             const char            *new_key)
+key_is_used (void       *prefs,
+             size_t      pref_size,
+             const char *new_key)
 {
-  MetaGenericPreference *p;
+  void *p = prefs;
 
-  for (p = prefs;
-       p->key != NULL;
-       p = (MetaGenericPreference *)((guchar *)p + pref_size))
+  while (TRUE)
     {
-      if (strcmp (p->key, new_key) == 0)
+      char **key = p;
+      if (*key == NULL)
+        break;
+
+      if (strcmp (*key, new_key) == 0)
         return TRUE;
+
+      p = (guchar *)p + pref_size;
     }
 
   return FALSE;
 }
 
 static gboolean
-do_override (MetaGenericPreference *prefs,
-             size_t                 pref_size,
-             const char            *search_key,
-             char                  *new_key)
+do_override (void       *prefs,
+             size_t      pref_size,
+             const char *search_key,
+             char       *new_key)
 {
-  MetaGenericPreference *p;
+  void *p = prefs;
 
-  for (p = prefs;
-       p->key != NULL;
-       p = (MetaGenericPreference *)((guchar *)p + pref_size))
+  while (TRUE)
     {
-      if (strcmp (p->key, search_key) == 0)
+      char **key = p;
+      if (*key == NULL)
+        break;
+
+      if (strcmp (*key, search_key) == 0)
         {
-          p->key = new_key;
+          *key = new_key;
           return TRUE;
         }
+
+      p = (guchar *)p + pref_size;
     }
 
   return FALSE;
@@ -1190,10 +1194,10 @@ meta_prefs_override_preference_location (const char *original_key,
   /* We depend on a unique mapping from GConf key to preference, so
    * enforce this */
 
-  if (key_is_used ((MetaGenericPreference *)preferences_enum, sizeof(MetaEnumPreference), new_key) ||
-      key_is_used ((MetaGenericPreference *)preferences_bool, sizeof(MetaBoolPreference), new_key) ||
-      key_is_used ((MetaGenericPreference *)preferences_string, sizeof(MetaStringPreference), new_key) ||
-      key_is_used ((MetaGenericPreference *)preferences_int, sizeof(MetaIntPreference), new_key))
+  if (key_is_used (preferences_enum, sizeof(MetaEnumPreference), new_key) ||
+      key_is_used (preferences_bool, sizeof(MetaBoolPreference), new_key) ||
+      key_is_used (preferences_string, sizeof(MetaStringPreference), new_key) ||
+      key_is_used (preferences_int, sizeof(MetaIntPreference), new_key))
     {
       meta_warning (_("GConf key %s is already in use and can't be used to override %s\n"),
                     new_key, original_key);
@@ -1216,10 +1220,10 @@ meta_prefs_override_preference_location (const char *original_key,
     }
 
   found =
-    do_override ((MetaGenericPreference *)preferences_enum, sizeof(MetaEnumPreference), search_key, new_key_copy) ||
-    do_override ((MetaGenericPreference *)preferences_bool, sizeof(MetaBoolPreference), search_key, new_key_copy) ||
-    do_override ((MetaGenericPreference *)preferences_string, sizeof(MetaStringPreference), search_key, new_key_copy) ||
-    do_override ((MetaGenericPreference *)preferences_int, sizeof(MetaIntPreference), search_key, new_key_copy);
+    do_override (preferences_enum, sizeof(MetaEnumPreference), search_key, new_key_copy) ||
+    do_override (preferences_bool, sizeof(MetaBoolPreference), search_key, new_key_copy) ||
+    do_override (preferences_string, sizeof(MetaStringPreference), search_key, new_key_copy) ||
+    do_override (preferences_int, sizeof(MetaIntPreference), search_key, new_key_copy);
   if (found)
     {
       if (overridden)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]