Description:
There is a C99 aliasing violation in the source of Mysql 5.1.40 which causes client
errors (specifically with MythTV but probably also with others) when Mysql is compiled
with -O3 optimization (GCC 4.4.2).
The problem is in in libmysql/libmysql.c, in the cli_stmt_execute() function. Line 2553
looks like:
for (param= stmt->params; param < param_end; param++)
store_param_type((char**) &net->write_pos, param);
And store_param_type is declared as:
static void store_param_type(char **pos, MYSQL_BIND *param)
{
uint typecode= param->buffer_type | (param->is_unsigned ? 32768 : 0);
int2store(*pos, typecode);
*pos+= 2;
}
However, the real type of net->write_pos is "uchar *" not "char *" and it is referenced
as such elsewhere in the cli_stmt_execute function. The types are incompatible and it is
not legal to access the net->write_pos value as if it were both a "uchar *" and "char *"
(note that if the "char **" cast is removed GCC gives a warning that the types are
incompatible).
The eventual result is that GCC thinks "*pos+=2" can be moved outside the loop and
collapsed to a single store. A bit silly, but that's what happens when you break the
aliasing rules :)
How to repeat:
Compile with GCC 4.4.2, using the Mysql-recommended CFLAGS/CXXFLAGS (I added only
-march=i686).
CXX=gcc CFLAGS="-O3 -march=i686" \
CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti -march=i686" \
./configure --prefix=/usr --localstatedir=/var/mysql --sysconfdir=/etc \
--mandir=/usr/share/man \
--enable-thread-safe-client --enable-assembler --with-gnu-ld \
--with-mysqld-user=mysql --with-ssl
make
make install
Then run "mythfrontend"...
Suggested fix:
The fix is fairly trivial, two things should be changed:
1) change the declared type of the "pos" parameter in store_param_type from "char **" to
"uchar **"
2) remove the "char **" cast from line 2554 in cli_stmt_execute. (Not strictly necessary,
but GCC gives a warning if you don't).
For a workaround with current version, it's easy just to add "-fno-strict-aliasing" to
CFLAGS.
Description: There is a C99 aliasing violation in the source of Mysql 5.1.40 which causes client errors (specifically with MythTV but probably also with others) when Mysql is compiled with -O3 optimization (GCC 4.4.2). The problem is in in libmysql/libmysql.c, in the cli_stmt_execute() function. Line 2553 looks like: for (param= stmt->params; param < param_end; param++) store_param_type((char**) &net->write_pos, param); And store_param_type is declared as: static void store_param_type(char **pos, MYSQL_BIND *param) { uint typecode= param->buffer_type | (param->is_unsigned ? 32768 : 0); int2store(*pos, typecode); *pos+= 2; } However, the real type of net->write_pos is "uchar *" not "char *" and it is referenced as such elsewhere in the cli_stmt_execute function. The types are incompatible and it is not legal to access the net->write_pos value as if it were both a "uchar *" and "char *" (note that if the "char **" cast is removed GCC gives a warning that the types are incompatible). The eventual result is that GCC thinks "*pos+=2" can be moved outside the loop and collapsed to a single store. A bit silly, but that's what happens when you break the aliasing rules :) How to repeat: Compile with GCC 4.4.2, using the Mysql-recommended CFLAGS/CXXFLAGS (I added only -march=i686). CXX=gcc CFLAGS="-O3 -march=i686" \ CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti -march=i686" \ ./configure --prefix=/usr --localstatedir=/var/mysql --sysconfdir=/etc \ --mandir=/usr/share/man \ --enable-thread-safe-client --enable-assembler --with-gnu-ld \ --with-mysqld-user=mysql --with-ssl make make install Then run "mythfrontend"... Suggested fix: The fix is fairly trivial, two things should be changed: 1) change the declared type of the "pos" parameter in store_param_type from "char **" to "uchar **" 2) remove the "char **" cast from line 2554 in cli_stmt_execute. (Not strictly necessary, but GCC gives a warning if you don't). For a workaround with current version, it's easy just to add "-fno-strict-aliasing" to CFLAGS.