1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Bug#42733: Type-punning warnings when compiling MySQL --

strict aliasing violations.

Essentially, the problem is that large parts of the server were
developed in simpler times (last decades, pre C99 standard) when
strict aliasing and compilers supporting such optimizations were
rare to non-existent. Thus, when compiling the server with a modern
compiler that uses strict aliasing rules to perform optimizations,
there are several places in the code that might trigger undefined
behavior.

As evinced by some recent bugs, GCC does a somewhat good of job
misoptimizing such code, but on the other hand also gives warnings
about suspicious code. One problem is that the warnings aren't
always accurate, yet we can't afford to just shut them off as we
might miss real cases. False-positive cases are aggravated mostly
by casts that are likely to trigger undefined behavior.

The solution is to start a cleanup process focused on fixing and
reducing the amount of strict-aliasing related warnings produced
by GCC and others compilers. A good deal of noise reduction can
be achieved by just removing useless casts that are product of
historical cruft and are likely to trigger undefined behavior if
dereferenced.

client/mysql.cc:
  Remove now-unnecessary casts.
  Break up large strings.
client/mysql_upgrade.c:
  Remove now-unnecessary casts.
client/mysqladmin.cc:
  Remove now-unnecessary casts.
  Break up large strings.
client/mysqlbinlog.cc:
  Remove now-unnecessary casts.
client/mysqlcheck.c:
  Remove now-unnecessary casts.
client/mysqldump.c:
  Remove now-unnecessary casts.
client/mysqlimport.c:
  Remove now-unnecessary casts.
client/mysqlshow.c:
  Remove now-unnecessary casts.
client/mysqlslap.c:
  Remove now-unnecessary casts.
client/mysqltest.cc:
  Remove now-unnecessary casts.
extra/comp_err.c:
  Remove now-unnecessary casts.
extra/my_print_defaults.c:
  Remove now-unnecessary casts.
  Break up large strings.
extra/mysql_waitpid.c:
  Remove now-unnecessary casts.
extra/perror.c:
  Remove now-unnecessary casts.
extra/resolve_stack_dump.c:
  Remove now-unnecessary casts.
extra/resolveip.c:
  Remove now-unnecessary casts.
include/my_getopt.h:
  Use a void pointer type as the opaque type to avoid problems with type
  incompatibility -- GCC issues warnings when the type name is not type
  compatible with a operand. As a side bonus, a explicit cast won't be
  necessary anymore.
include/sslopt-longopts.h:
  Remove now-unnecessary casts.
  Break up large strings.
mysys/my_getopt.c:
  Update opaque type and introduce a type definition for the
  argument to my_getopt_register_get_addr.
server-tools/instance-manager/options.cc:
  Remove now-unnecessary casts.
sql/mysqld.cc:
  Remove now-unnecessary casts.
  Break up large strings.
  Update mysql_getopt_value prototype (the old prototype
  was different from the definition anyway).
sql/sql_plugin.cc:
  The type of a pointer to a function must be compatible with the
  pointed-to function type, otherwise the behavior is undefined.
sql/table.cc:
  The variable buf pointer to pointer to pointer to constant char
  could improperly alias a incompatible type in call to fix_type_
  pointers. Since this was actually dead code, it is simply removed.
sql/unireg.cc:
  Remove call to get_form_pos. The code creates a new FRM file which
  is always truncated and writes the form position as 0. Hence, no
  need to retrieve it, we now for sure it is 0.
storage/archive/archive_reader.c:
  Remove now-unnecessary casts.
storage/myisam/ft_nlq_search.c:
  Read weight directly from the buffer.
storage/myisam/fulltext.h:
  Add explanation about the type duality of a key buffer.
  Add accessor macro to retrieve a FT float value.
storage/myisam/mi_test1.c:
  Remove now-unnecessary casts.
storage/myisam/myisam_ftdump.c:
  Read weight directly from the buffer.
storage/myisam/myisamchk.c:
  Remove now-unnecessary casts.
storage/myisam/myisamlog.c:
  A pointer to char was used to alias a pointer to pointer to
  unsigned char, thus violating strict aliasing rules.
storage/myisam/myisampack.c:
  Remove now-unnecessary casts.
strings/decimal.c:
  Remove aliasing violation, printing the value is enough for
  debugging purposes.
tests/mysql_client_test.c:
  Remove now-unnecessary casts.
This commit is contained in:
Davi Arnaut
2010-06-10 17:16:43 -03:00
parent a24df71e95
commit 6f3a540c37
35 changed files with 1248 additions and 1111 deletions

View File

@ -511,62 +511,62 @@ static struct my_option my_long_options[] =
0, 0, 0, 0, 0, 0},
{"auto-generate-sql", 'a',
"Generate SQL where not supplied by file or command line.",
(uchar**) &auto_generate_sql, (uchar**) &auto_generate_sql,
&auto_generate_sql, &auto_generate_sql,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"auto-generate-sql-add-autoincrement", OPT_SLAP_AUTO_GENERATE_ADD_AUTO,
"Add an AUTO_INCREMENT column to auto-generated tables.",
(uchar**) &auto_generate_sql_autoincrement,
(uchar**) &auto_generate_sql_autoincrement,
&auto_generate_sql_autoincrement,
&auto_generate_sql_autoincrement,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"auto-generate-sql-execute-number", OPT_SLAP_AUTO_GENERATE_EXECUTE_QUERIES,
"Set this number to generate a set number of queries to run.",
(uchar**) &auto_actual_queries, (uchar**) &auto_actual_queries,
&auto_actual_queries, &auto_actual_queries,
0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"auto-generate-sql-guid-primary", OPT_SLAP_AUTO_GENERATE_GUID_PRIMARY,
"Add GUID based primary keys to auto-generated tables.",
(uchar**) &auto_generate_sql_guid_primary,
(uchar**) &auto_generate_sql_guid_primary,
&auto_generate_sql_guid_primary,
&auto_generate_sql_guid_primary,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"auto-generate-sql-load-type", OPT_SLAP_AUTO_GENERATE_SQL_LOAD_TYPE,
"Specify test load type: mixed, update, write, key, or read; default is mixed.",
(uchar**) &auto_generate_sql_type, (uchar**) &auto_generate_sql_type,
&auto_generate_sql_type, &auto_generate_sql_type,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"auto-generate-sql-secondary-indexes",
OPT_SLAP_AUTO_GENERATE_SECONDARY_INDEXES,
"Number of secondary indexes to add to auto-generated tables.",
(uchar**) &auto_generate_sql_secondary_indexes,
(uchar**) &auto_generate_sql_secondary_indexes, 0,
&auto_generate_sql_secondary_indexes,
&auto_generate_sql_secondary_indexes, 0,
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"auto-generate-sql-unique-query-number",
OPT_SLAP_AUTO_GENERATE_UNIQUE_QUERY_NUM,
"Number of unique queries to generate for automatic tests.",
(uchar**) &auto_generate_sql_unique_query_number,
(uchar**) &auto_generate_sql_unique_query_number,
&auto_generate_sql_unique_query_number,
&auto_generate_sql_unique_query_number,
0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
{"auto-generate-sql-unique-write-number",
OPT_SLAP_AUTO_GENERATE_UNIQUE_WRITE_NUM,
"Number of unique queries to generate for auto-generate-sql-write-number.",
(uchar**) &auto_generate_sql_unique_write_number,
(uchar**) &auto_generate_sql_unique_write_number,
&auto_generate_sql_unique_write_number,
&auto_generate_sql_unique_write_number,
0, GET_ULL, REQUIRED_ARG, 10, 0, 0, 0, 0, 0},
{"auto-generate-sql-write-number", OPT_SLAP_AUTO_GENERATE_WRITE_NUM,
"Number of row inserts to perform for each thread (default is 100).",
(uchar**) &auto_generate_sql_number, (uchar**) &auto_generate_sql_number,
&auto_generate_sql_number, &auto_generate_sql_number,
0, GET_ULL, REQUIRED_ARG, 100, 0, 0, 0, 0, 0},
{"commit", OPT_SLAP_COMMIT, "Commit records every X number of statements.",
(uchar**) &commit_rate, (uchar**) &commit_rate, 0, GET_UINT, REQUIRED_ARG,
&commit_rate, &commit_rate, 0, GET_UINT, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"compress", 'C', "Use compression in server/client protocol.",
(uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
&opt_compress, &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
{"concurrency", 'c', "Number of clients to simulate for query to run.",
(uchar**) &concurrency_str, (uchar**) &concurrency_str, 0, GET_STR,
&concurrency_str, &concurrency_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"create", OPT_SLAP_CREATE_STRING, "File or string to use create tables.",
(uchar**) &create_string, (uchar**) &create_string, 0, GET_STR, REQUIRED_ARG,
&create_string, &create_string, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"create-schema", OPT_CREATE_SLAP_SCHEMA, "Schema to run tests in.",
(uchar**) &create_schema_string, (uchar**) &create_schema_string, 0, GET_STR,
&create_schema_string, &create_schema_string, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"csv", OPT_SLAP_CSV,
"Generate CSV output to named file or to stdout if no file is named.",
@ -576,45 +576,45 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
#else
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
(uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR,
&default_dbug_option, &default_dbug_option, 0, GET_STR,
OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
(uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0,
&debug_check_flag, &debug_check_flag, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"debug-info", 'T', "Print some debug info at exit.", (uchar**) &debug_info_flag,
(uchar**) &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"debug-info", 'T', "Print some debug info at exit.", &debug_info_flag,
&debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"delimiter", 'F',
"Delimiter to use in SQL statements supplied in file or command line.",
(uchar**) &delimiter, (uchar**) &delimiter, 0, GET_STR, REQUIRED_ARG,
&delimiter, &delimiter, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"detach", OPT_SLAP_DETACH,
"Detach (close and reopen) connections after X number of requests.",
(uchar**) &detach_rate, (uchar**) &detach_rate, 0, GET_UINT, REQUIRED_ARG,
&detach_rate, &detach_rate, 0, GET_UINT, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"engine", 'e', "Storage engine to use for creating the table.",
(uchar**) &default_engine, (uchar**) &default_engine, 0,
&default_engine, &default_engine, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", (uchar**) &host, (uchar**) &host, 0, GET_STR,
{"host", 'h', "Connect to host.", &host, &host, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"iterations", 'i', "Number of times to run the tests.", (uchar**) &iterations,
(uchar**) &iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
{"iterations", 'i', "Number of times to run the tests.", &iterations,
&iterations, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
{"number-char-cols", 'x',
"Number of VARCHAR columns to create in table if specifying --auto-generate-sql.",
(uchar**) &num_char_cols_opt, (uchar**) &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
&num_char_cols_opt, &num_char_cols_opt, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"number-int-cols", 'y',
"Number of INT columns to create in table if specifying --auto-generate-sql.",
(uchar**) &num_int_cols_opt, (uchar**) &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG,
&num_int_cols_opt, &num_int_cols_opt, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
{"number-of-queries", OPT_MYSQL_NUMBER_OF_QUERY,
"Limit each client to this number of queries (this is not exact).",
(uchar**) &num_of_query, (uchar**) &num_of_query, 0,
&num_of_query, &num_of_query, 0,
GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"only-print", OPT_MYSQL_ONLY_PRINT,
"Do not connect to the databases, but instead print out what would have "
"been done.",
(uchar**) &opt_only_print, (uchar**) &opt_only_print, 0, GET_BOOL, NO_ARG,
&opt_only_print, &opt_only_print, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"password", 'p',
"Password to use when connecting to server. If password is not given it's "
@ -623,58 +623,54 @@ static struct my_option my_long_options[] =
{"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"port", 'P', "Port number to use for connection.", (uchar**) &opt_mysql_port,
(uchar**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
{"port", 'P', "Port number to use for connection.", &opt_mysql_port,
&opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0,
0},
{"post-query", OPT_SLAP_POST_QUERY,
"Query to run or file containing query to execute after tests have completed.",
(uchar**) &user_supplied_post_statements,
(uchar**) &user_supplied_post_statements,
&user_supplied_post_statements, &user_supplied_post_statements,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"post-system", OPT_SLAP_POST_SYSTEM,
"system() string to execute after tests have completed.",
(uchar**) &post_system,
(uchar**) &post_system,
&post_system, &post_system,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"pre-query", OPT_SLAP_PRE_QUERY,
"Query to run or file containing query to execute before running tests.",
(uchar**) &user_supplied_pre_statements,
(uchar**) &user_supplied_pre_statements,
&user_supplied_pre_statements, &user_supplied_pre_statements,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"pre-system", OPT_SLAP_PRE_SYSTEM,
"system() string to execute before running tests.",
(uchar**) &pre_system,
(uchar**) &pre_system,
&pre_system, &pre_system,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"protocol", OPT_MYSQL_PROTOCOL,
"The protocol to use for connection (tcp, socket, pipe, memory).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"query", 'q', "Query to run or file containing query to run.",
(uchar**) &user_supplied_query, (uchar**) &user_supplied_query,
&user_supplied_query, &user_supplied_query,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_SMEM
{"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
"Base name of shared memory.", (uchar**) &shared_memory_base_name,
(uchar**) &shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG,
"Base name of shared memory.", &shared_memory_base_name,
&shared_memory_base_name, 0, GET_STR_ALLOC, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
#endif
{"silent", 's', "Run program in silent mode - no output.",
(uchar**) &opt_silent, (uchar**) &opt_silent, 0, GET_BOOL, NO_ARG,
&opt_silent, &opt_silent, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{"socket", 'S', "The socket file to use for connection.",
(uchar**) &opt_mysql_unix_port, (uchar**) &opt_mysql_unix_port, 0, GET_STR,
&opt_mysql_unix_port, &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include <sslopt-longopts.h>
#ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", (uchar**) &user,
(uchar**) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"user", 'u', "User for login if not current user.", &user,
&user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"verbose", 'v',
"More verbose output; you can use this multiple times to get even more "
"verbose output.", (uchar**) &verbose, (uchar**) &verbose, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
"More verbose output; you can use this multiple times to get even more "
"verbose output.", &verbose, &verbose, 0, GET_NO_ARG, NO_ARG,
0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};