From: Davi Arnaut Date: July 5 2010 8:51pm Subject: bzr commit into mysql-5.1-bugteam branch (davi:3459) Bug#42733 List-Archive: http://lists.mysql.com/commits/112919 X-Bug: 42733 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============5756912661485260343==" --===============5756912661485260343== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline # At a local mysql-5.1-bugteam repository of davi 3459 Davi Arnaut 2010-07-05 Bug#42733: Type-punning warnings when compiling MySQL -- strict aliasing violations. Another rather noisy violation of strict aliasing rules is the spatial code which makes use of stack-based memory (of type Geometry_buffer) to provide placement for Geometry objects. Although a placement new is allowed to dynamically change the type of a object, the object returned by the new placement was being ignored and the original stack-based object was being casted to the new type, thus violating strict aliasing rules. The solution is to reorganize the code so that the object returned by the new placement is used instead of casting the original object. Also, to ensure that the stack-based object is properly aligned with respect to the objects it provides placement for, a set of compiler-dependent macros and types are introduced so that the alignment of objects can be inquired and specified. @ include/Makefile.am Add new header. @ include/my_compiler.h Add header to house compiler-dependent features. Use compiler/version to detect available features at build time instead of configure time in order to avoid common pitfalls in autoconf-based checks (such as attributes being ignored by certain compilers). Add macros to inquire and set alignment. Add my_aligned_storage which is similar to the C++0x aligned_storage type, which provides a POD-type suitable for use as uninitialized storage for any object. Use partial template specialization due to historical weakness of using attributes with template arguments. @ include/my_global.h Remove now-unnecessary macros. @ sql/spatial.cc Make object creation functions return the object whose type was dynamically changed by the new placement. Move static method from the header in order to avoid having to access a forward declaration. @ sql/spatial.h Object creation callbacks now take a array of chars as the storage area. Move create_by_typeid to a source file as to not access the forward declaration of Geometry_buffer. Ensure that Geometry_buffer is properly aligned. @ sql/sql_show.cc Use newly added aligned storage helper. added: include/my_compiler.h modified: include/Makefile.am include/my_global.h sql/spatial.cc sql/spatial.h sql/sql_show.cc === modified file 'include/Makefile.am' --- a/include/Makefile.am 2009-03-20 11:18:29 +0000 +++ b/include/Makefile.am 2010-07-05 20:51:07 +0000 @@ -36,7 +36,7 @@ noinst_HEADERS = config-win.h config-net my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ - my_handler.h my_time.h \ + my_handler.h my_time.h my_compiler.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \ atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h === added file 'include/my_compiler.h' --- a/include/my_compiler.h 1970-01-01 00:00:00 +0000 +++ b/include/my_compiler.h 2010-07-05 20:51:07 +0000 @@ -0,0 +1,127 @@ +#ifndef MY_COMPILER_INCLUDED +#define MY_COMPILER_INCLUDED + +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/** + Header for compiler-dependent features. + + Intended to contain a set of reusable wrappers for preprocessor + macros, attributes, pragmas, and any other features that are + specific to a target compiler. +*/ + +#include /* stddef.h offsetof */ + +/** + Compiler-dependent internal convenience macros. +*/ + +/* GNU C/C++ */ +#if defined __GNUC__ +/* Any after 2.95... */ +# define MY_ALIGN_EXT + +/* Microsoft Visual C++ */ +#elif defined _MSC_VER +# define MY_ALIGNOF(type) __alignof(type) +# define MY_ALIGNED(n) __declspec(align(n)) + +/* Oracle Solaris Studio */ +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# if __SUNPRO_CC >= 0x590 +# define MY_ALIGN_EXT +# endif + +/* IBM XL C/C++ */ +#elif defined __xlC__ +# if __xlC__ >= 0x0600 +# define MY_ALIGN_EXT +# endif + +/* HP aCC */ +#elif defined(__HP_aCC) || defined(__HP_cc) +# if (__HP_aCC >= 60000) || (__HP_cc >= 60000) +# define MY_ALIGN_EXT +# endif +#endif + +#ifdef MY_ALIGN_EXT +/** Specifies the minimum alignment of a type. */ +# define MY_ALIGNOF(type) __alignof__(type) +/** Determine the alignment requirement of a type. */ +# define MY_ALIGNED(n) __attribute__((__aligned__((n)))) +#endif + +/** + Generic compiler-dependent features. +*/ +#ifndef MY_ALIGNOF +# ifdef __cplusplus + /* Invalid for non-POD types, but most compilers give the right answer. */ + template struct my_alignof_helper { char m1; type m2; }; +# define MY_ALIGNOF(type) offsetof(my_alignof_helper, m2) +# else +# define MY_ALIGNOF(type) offsetof(struct { char m1; type m2; }, m2) +# endif +#endif + +/** + C++ Type Traits +*/ + +#ifdef __cplusplus + +/** + Opaque storage with a particular alignment. +*/ +# if defined(MY_ALIGNED) +/* Partial specialization used due to MSVC++. */ +template struct my_alignment_imp; +template<> struct MY_ALIGNED(1) my_alignment_imp<1> {}; +template<> struct MY_ALIGNED(2) my_alignment_imp<2> {}; +template<> struct MY_ALIGNED(4) my_alignment_imp<4> {}; +template<> struct MY_ALIGNED(8) my_alignment_imp<8> {}; +template<> struct MY_ALIGNED(16) my_alignment_imp<16> {}; +/* ... expand as necessary. */ +# else +template +struct my_alignment_imp { double m1; }; +# endif + +/** + A POD type with a given size and alignment. + + @remark If the compiler does not support a alignment attribute + (MY_ALIGN macro), the default alignment of a double is + used instead. + + @tparam size The minimum size. + @tparam alignment The desired alignment: 1, 2, 4, 8 or 16. +*/ +template +struct my_aligned_storage +{ + union + { + char data[size]; + my_alignment_imp align; + }; +}; + +#endif /* __cplusplus */ + +#endif /* MY_COMPILER_INCLUDED */ === modified file 'include/my_global.h' --- a/include/my_global.h 2010-07-02 18:30:47 +0000 +++ b/include/my_global.h 2010-07-05 20:51:07 +0000 @@ -941,9 +941,6 @@ typedef long long my_ptrdiff_t; #define ADD_TO_PTR(ptr,size,type) (type) ((uchar*) (ptr)+size) #define PTR_BYTE_DIFF(A,B) (my_ptrdiff_t) ((uchar*) (A) - (uchar*) (B)) -#define MY_DIV_UP(A, B) (((A) + (B) - 1) / (B)) -#define MY_ALIGNED_BYTE_ARRAY(N, S, T) T N[MY_DIV_UP(S, sizeof(T))] - /* Custom version of standard offsetof() macro which can be used to get offsets of members in class for non-POD types (according to the current === modified file 'sql/spatial.cc' --- a/sql/spatial.cc 2009-08-28 16:21:54 +0000 +++ b/sql/spatial.cc 2010-07-05 20:51:07 +0000 @@ -53,7 +53,7 @@ static Geometry::Class_info **ci_collect Geometry::ci_collection+Geometry::wkb_last + 1; Geometry::Class_info::Class_info(const char *name, int type_id, - void(*create_func)(void *)): + create_geom_t create_func): m_type_id(type_id), m_create_func(create_func) { m_name.str= (char *) name; @@ -62,39 +62,39 @@ Geometry::Class_info::Class_info(const c ci_collection[type_id]= this; } -static void create_point(void *buffer) +static Geometry *create_point(char *buffer) { - new(buffer) Gis_point; + return new (buffer) Gis_point; } -static void create_linestring(void *buffer) +static Geometry *create_linestring(char *buffer) { - new(buffer) Gis_line_string; + return new (buffer) Gis_line_string; } -static void create_polygon(void *buffer) +static Geometry *create_polygon(char *buffer) { - new(buffer) Gis_polygon; + return new (buffer) Gis_polygon; } -static void create_multipoint(void *buffer) +static Geometry *create_multipoint(char *buffer) { - new(buffer) Gis_multi_point; + return new (buffer) Gis_multi_point; } -static void create_multipolygon(void *buffer) +static Geometry *create_multipolygon(char *buffer) { - new(buffer) Gis_multi_polygon; + return new (buffer) Gis_multi_polygon; } -static void create_multilinestring(void *buffer) +static Geometry *create_multilinestring(char *buffer) { - new(buffer) Gis_multi_line_string; + return new (buffer) Gis_multi_line_string; } -static void create_geometrycollection(void *buffer) +static Geometry *create_geometrycollection(char *buffer) { - new(buffer) Gis_geometry_collection; + return new (buffer) Gis_geometry_collection; } @@ -145,6 +145,15 @@ Geometry::Class_info *Geometry::find_cla } +Geometry *Geometry::create_by_typeid(Geometry_buffer *buffer, int type_id) +{ + Class_info *ci; + if (!(ci= find_class(type_id))) + return NULL; + return (*ci->m_create_func)(buffer->data); +} + + Geometry *Geometry::construct(Geometry_buffer *buffer, const char *data, uint32 data_len) { @@ -170,6 +179,7 @@ Geometry *Geometry::create_from_wkt(Geom { LEX_STRING name; Class_info *ci; + Geometry *result; if (trs->get_next_word(&name)) { @@ -179,9 +189,7 @@ Geometry *Geometry::create_from_wkt(Geom if (!(ci= find_class(name.str, name.length)) || wkt->reserve(1 + 4, 512)) return NULL; - (*ci->m_create_func)((void *)buffer); - Geometry *result= (Geometry *)buffer; - + result= (*ci->m_create_func)(buffer->data); wkt->q_append((char) wkb_ndr); wkt->q_append((uint32) result->get_class_info()->m_type_id); if (trs->check_next_symbol('(') || === modified file 'sql/spatial.h' --- a/sql/spatial.h 2009-06-17 14:56:44 +0000 +++ b/sql/spatial.h 2010-07-05 20:51:07 +0000 @@ -16,6 +16,8 @@ #ifndef _spatial_h #define _spatial_h +#include + #ifdef HAVE_SPATIAL const uint SRID_SIZE= 4; @@ -227,13 +229,15 @@ public: wkb_ndr= 1 /* Little Endian */ }; + typedef Geometry *(*create_geom_t)(char *); + class Class_info { public: LEX_STRING m_name; int m_type_id; - void (*m_create_func)(void *); - Class_info(const char *name, int type_id, void(*create_func)(void *)); + create_geom_t m_create_func; + Class_info(const char *name, int type_id, create_geom_t create_func); }; virtual const Class_info *get_class_info() const=0; @@ -263,15 +267,7 @@ public: virtual int geometry_n(uint32 num, String *result) const { return -1; } public: - static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id) - { - Class_info *ci; - if (!(ci= find_class((int) type_id))) - return NULL; - (*ci->m_create_func)((void *)buffer); - return my_reinterpret_cast(Geometry *)(buffer); - } - + static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id); static Geometry *construct(Geometry_buffer *buffer, const char *data, uint32 data_len); static Geometry *create_from_wkt(Geometry_buffer *buffer, @@ -528,11 +524,8 @@ public: const Class_info *get_class_info() const; }; -const int geometry_buffer_size= sizeof(Gis_point); -struct Geometry_buffer -{ - void *arr[(geometry_buffer_size - 1)/sizeof(void *) + 1]; -}; +struct Geometry_buffer : + my_aligned_storage {}; #endif /*HAVE_SPATAIAL*/ #endif === modified file 'sql/sql_show.cc' --- a/sql/sql_show.cc 2010-06-25 08:01:47 +0000 +++ b/sql/sql_show.cc 2010-07-05 20:51:07 +0000 @@ -2202,8 +2202,8 @@ static bool show_status_array(THD *thd, bool ucase_names, COND *cond) { - MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long); - char * const buff= (char *) &buff_data; + my_aligned_storage buffer; + char * const buff= buffer.data; char *prefix_end; /* the variable name should not be longer than 64 characters */ char name_buffer[64]; --===============5756912661485260343== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/davi.arnaut@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: davi.arnaut@stripped # target_branch: file:///home/davi/bzr/bugs/42733-5.1/ # testament_sha1: 2d7b56744abc58045a6d81c246c910e7c12df132 # timestamp: 2010-07-05 17:51:17 -0300 # base_revision_id: davi.arnaut@stripped\ # fyw33fu1rc9j6qzw # # Begin bundle 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 hI+8XckU4UJAMvEceA== --===============5756912661485260343==--