From cb6a084076d4688c11936bfa91b03a83570f69e0 Mon Sep 17 00:00:00 2001
From: "jimw@rama.(none)" <>
Date: Thu, 17 Aug 2006 12:25:40 -0700
Subject: [PATCH] Bug #2717: include/my_global.h mis-defines __attribute__

  Fix when __attribute__() is stubbed out, add ATTRIBUTE_FORMAT() for specifying
  __attribute__((format(...))) safely, make more use of the format attribute,
  and fix some of the warnings that this turns up (plus a bonus unrelated one).
---
 include/m_ctype.h     |  5 +++--
 include/m_string.h    |  3 ++-
 include/my_global.h   | 22 +++++++++++++++++++++-
 include/my_sys.h      |  4 ++--
 sql/item_subselect.cc |  2 +-
 sql/item_timefunc.cc  |  4 ++--
 sql/mysql_priv.h      | 11 ++++++-----
 sql/mysqld.cc         | 21 +++++++++++----------
 sql/opt_range.cc      |  7 ++++---
 sql/set_var.cc        | 12 ++++++------
 sql/slave.cc          |  2 +-
 sql/slave.h           |  3 ++-
 sql/sql_acl.cc        |  4 ++--
 sql/sql_class.h       |  2 +-
 14 files changed, 64 insertions(+), 38 deletions(-)

diff --git a/include/m_ctype.h b/include/m_ctype.h
index cd1dac9dde..b2bf8d3e30 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -175,7 +175,7 @@ typedef struct my_charset_handler_st
   
   /* Charset dependant snprintf() */
   int  (*snprintf)(struct charset_info_st *, char *to, uint n, const char *fmt,
-		   ...);
+		   ...) ATTRIBUTE_FORMAT(printf, 4, 5);
   int  (*long10_to_str)(struct charset_info_st *, char *to, uint n, int radix,
 			long int val);
   int (*longlong10_to_str)(struct charset_info_st *, char *to, uint n,
@@ -300,7 +300,8 @@ int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc, uchar *s, uchar *e);
 ulong my_scan_8bit(CHARSET_INFO *cs, const char *b, const char *e, int sq);
 
 int my_snprintf_8bit(struct charset_info_st *, char *to, uint n,
-		     const char *fmt, ...);
+		     const char *fmt, ...)
+  ATTRIBUTE_FORMAT(printf, 4, 5);
 
 long        my_strntol_8bit(CHARSET_INFO *, const char *s, uint l, int base,
 			    char **e, int *err);
diff --git a/include/m_string.h b/include/m_string.h
index d7edff4f62..08408c372b 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -247,7 +247,8 @@ extern ulonglong strtoull(const char *str, char **ptr, int base);
 
 extern int my_vsnprintf( char *str, size_t n,
                                 const char *format, va_list ap );
-extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
+extern int my_snprintf(char *to, size_t n, const char *fmt, ...)
+  ATTRIBUTE_FORMAT(printf, 3, 4);
 
 #if defined(__cplusplus) && !defined(OS2)
 }
diff --git a/include/my_global.h b/include/my_global.h
index 6baa4558d5..2fbb1db4b7 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -414,14 +414,34 @@ typedef unsigned short ushort;
 #define function_volatile	volatile
 #define my_reinterpret_cast(A) reinterpret_cast<A>
 #define my_const_cast(A) const_cast<A>
+# ifndef GCC_VERSION
+#  define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+# endif
 #elif !defined(my_reinterpret_cast)
 #define my_reinterpret_cast(A) (A)
 #define my_const_cast(A) (A)
 #endif
-#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__)  || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+
+/*
+  Disable __attribute__() on GCC < 2.7 and non-GCC compilers
+*/
+#if !defined(__attribute__) && (!defined(__GNUC__) || GCC_VERSION < 2007)
 #define __attribute__(A)
 #endif
 
+/*
+  __attribute__((format(...))) is only supported in gcc >= 2.8 and g++ >= 3.4
+*/
+#ifndef ATTRIBUTE_FORMAT
+# if defined(__GNUC__) && \
+     ((!defined(__cplusplus__) && GCC_VERSION >= 2008) || \
+      GCC_VERSION >= 3004)
+#  define ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n)))
+# else
+#  define ATTRIBUTE_FORMAT(style, m, n)
+# endif
+#endif
+
 /* From old s-system.h */
 
 /*
diff --git a/include/my_sys.h b/include/my_sys.h
index 02ea188a18..46e09e8ddf 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -588,8 +588,8 @@ extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
 extern int my_sync(File fd, myf my_flags);
 extern int my_error _VARARGS((int nr,myf MyFlags, ...));
 extern int my_printf_error _VARARGS((uint my_err, const char *format,
-				     myf MyFlags, ...)
-				    __attribute__ ((format (printf, 2, 4))));
+				     myf MyFlags, ...))
+                                    ATTRIBUTE_FORMAT(printf, 2, 4);
 extern int my_message(uint my_err, const char *str,myf MyFlags);
 extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags);
 extern int my_message_curses(uint my_err, const char *str,myf MyFlags);
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index c95a91de13..006153cc51 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -545,7 +545,7 @@ Item_allany_subselect::Item_allany_subselect(Item * left_exp,
                                              chooser_compare_func_creator fc,
 					     st_select_lex *select_lex,
 					     bool all_arg)
-  :Item_in_subselect(), all(all_arg), func_creator(fc)
+  :Item_in_subselect(), func_creator(fc), all(all_arg)
 {
   DBUG_ENTER("Item_in_subselect::Item_in_subselect");
   left_expr= left_exp;
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 44d9b42226..21e27d6c7b 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -65,7 +65,7 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
 			       ltime->hour, ltime->minute, ltime->second);
     break;
   case TIME_MICROSECOND:
-    length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d.%06d",
+    length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d.%06ld",
 			       ltime->neg ? "-" : "",
 			       ltime->hour, ltime->minute, ltime->second,
 			       ltime->second_part);
@@ -82,7 +82,7 @@ static bool make_datetime(date_time_format_types format, TIME *ltime,
     break;
   case DATE_TIME_MICROSECOND:
     length= cs->cset->snprintf(cs, buff, length,
-			       "%04d-%02d-%02d %02d:%02d:%02d.%06d",
+			       "%04d-%02d-%02d %02d:%02d:%02d.%06ld",
 			       ltime->year, ltime->month, ltime->day,
 			       ltime->hour, ltime->minute, ltime->second,
 			       ltime->second_part);
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 9c5bcc2d53..76627eaf3e 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -712,7 +712,8 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
 MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code,
                           const char *msg);
 void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
-			 uint code, const char *format, ...);
+                         uint code, const char *format, ...)
+  ATTRIBUTE_FORMAT(printf,4,5);
 void mysql_reset_errors(THD *thd);
 my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
 
@@ -847,10 +848,10 @@ bool init_errmessage(void);
 void sql_perror(const char *message);
 
 void vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
-void sql_print_error(const char *format, ...);
-void sql_print_warning(const char *format, ...);
-void sql_print_information(const char *format, ...);
-
+void sql_print_error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
+void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
+void sql_print_information(const char *format, ...)
+  ATTRIBUTE_FORMAT(printf, 1, 2);
 
 
 bool fn_format_relative_to_data_home(my_string to, const char *name,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 74c7b1a4e4..ba0a7d134f 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -952,8 +952,8 @@ extern "C" sig_handler print_signal_warning(int sig)
   if (!DBUG_IN_USE)
   {
     if (global_system_variables.log_warnings)
-      sql_print_warning("Got signal %d from thread %d",
-		      sig,my_thread_id());
+      sql_print_warning("Got signal %d from thread %ld",
+                        sig, my_thread_id());
   }
 #ifdef DONT_REMEMBER_SIGNAL
   my_sigset(sig,print_signal_warning);		/* int. thread system calls */
@@ -1443,8 +1443,8 @@ static void server_init(void)
 
     if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
     {
-      sql_print_error("The socket file path is too long (> %d): %s",
-                    sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
+      sql_print_error("The socket file path is too long (> %lu): %s",
+                      sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
       unireg_abort(1);
     }
     if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
@@ -2786,9 +2786,9 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
     sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
     abort();
   }
-  if (err) 
+  if (err)
   {
-    sql_print_error("Fatal: can't %s OpenSSL %s lock", what);
+    sql_print_error("Fatal: can't %s OpenSSL lock", what);
     abort();
   }
 }
@@ -6549,14 +6549,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
       exit(1);
     }
     switch (method-1) {
-    case 0: 
-      method_conv= MI_STATS_METHOD_NULLS_EQUAL;
+    case 2:
+      method_conv= MI_STATS_METHOD_IGNORE_NULLS;
       break;
     case 1:
       method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
       break;
-    case 2:
-      method_conv= MI_STATS_METHOD_IGNORE_NULLS;
+    case 0:
+    default:
+      method_conv= MI_STATS_METHOD_NULLS_EQUAL;
       break;
     }
     global_system_variables.myisam_stats_method= method_conv;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 57903ffe7b..f5e8a799c4 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2513,8 +2513,9 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
       ulong count=count_key_part_usage(root,pos->next_key_part);
       if (count > pos->next_key_part->use_count)
       {
-	sql_print_information("Use_count: Wrong count for key at %lx, %lu should be %lu",
-			pos,pos->next_key_part->use_count,count);
+        sql_print_information("Use_count: Wrong count for key at %lx, %lu "
+                              "should be %lu", (long unsigned int)pos,
+                              pos->next_key_part->use_count, count);
 	return;
       }
       pos->next_key_part->test_use_count(root);
@@ -2522,7 +2523,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
   }
   if (e_count != elements)
     sql_print_warning("Wrong use count: %u (should be %u) for tree at %lx",
-		    e_count, elements, (gptr) this);
+                      e_count, elements, (long unsigned int) this);
 }
 
 #endif
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 1d994f1c98..8d6db6bf68 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1150,14 +1150,14 @@ static void fix_net_retry_count(THD *thd, enum_var_type type)
     thd->net.retry_count=thd->variables.net_retry_count;
 }
 #else /* HAVE_REPLICATION */
-static void fix_net_read_timeout(THD *thd __attribute__(unused),
-				 enum_var_type type __attribute__(unused))
+static void fix_net_read_timeout(THD *thd __attribute__((unused)),
+				 enum_var_type type __attribute__((unused)))
 {}
-static void fix_net_write_timeout(THD *thd __attribute__(unused),
-				  enum_var_type type __attribute__(unused))
+static void fix_net_write_timeout(THD *thd __attribute__((unused)),
+				  enum_var_type type __attribute__((unused)))
 {}
-static void fix_net_retry_count(THD *thd __attribute__(unused),
-				enum_var_type type __attribute__(unused))
+static void fix_net_retry_count(THD *thd __attribute__((unused)),
+				enum_var_type type __attribute__((unused)))
 {}
 #endif /* HAVE_REPLICATION */
 
diff --git a/sql/slave.cc b/sql/slave.cc
index b2862a437b..ff1da2541d 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -4073,7 +4073,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
       suppress_warnings= 0;
       sql_print_error("Slave I/O thread: error %s to master \
 '%s@%s:%d': \
-Error: '%s'  errno: %d  retry-time: %d  retries: %d",
+Error: '%s'  errno: %d  retry-time: %d  retries: %lu",
 		      (reconnect ? "reconnecting" : "connecting"),
 		      mi->user,mi->host,mi->port,
 		      mysql_error(mysql), last_errno,
diff --git a/sql/slave.h b/sql/slave.h
index f780b7c847..dccfcf01a8 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -551,7 +551,8 @@ const char *rewrite_db(const char* db, uint32 *new_db_len);
 const char *print_slave_db_safe(const char *db);
 int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
 void skip_load_data_infile(NET* net);
-void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...);
+void slave_print_error(RELAY_LOG_INFO *rli, int err_code, const char *msg, ...)
+  ATTRIBUTE_FORMAT(printf, 3, 4);
 
 void end_slave(); /* clean up */
 void init_master_info_with_options(MASTER_INFO* mi);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 734bccb6b4..affab49065 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -426,7 +426,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
                           "case that has been forced to lowercase because "
                           "lower_case_table_names is set. It will not be "
                           "possible to remove this privilege using REVOKE.",
-		          db.db, db.user, db.host.hostname, db.host.hostname);
+		          db.db, db.user, db.host.hostname);
       }
     }
     db.sort=get_sort(3,db.host.hostname,db.db,db.user);
@@ -2778,7 +2778,7 @@ static my_bool grant_load(TABLE_LIST *tables)
         sql_print_warning("'tables_priv' entry '%s %s@%s' "
                           "ignored in --skip-name-resolve mode.",
                           mem_check->tname, mem_check->user,
-                          mem_check->host);
+                          mem_check->host.hostname);
 	continue;
       }
     }
diff --git a/sql/sql_class.h b/sql/sql_class.h
index e8fe175cd7..fe5ceb4c75 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -145,7 +145,7 @@ public:
 	    bool no_auto_events_arg, ulong max_size);
   void new_file(bool need_lock= 1);
   bool write(THD *thd, enum enum_server_command command,
-	     const char *format,...);
+	     const char *format, ...) ATTRIBUTE_FORMAT(printf, 4, 5);
   bool write(THD *thd, const char *query, uint query_length,
 	     time_t query_start=0);
   bool write(Log_event* event_info); // binary log write
-- 
2.30.9