summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuilhem Bichot <guilhem@mysql.com>2010-11-22 09:57:59 +0100
committerGuilhem Bichot <guilhem@mysql.com>2010-11-22 09:57:59 +0100
commit96b0404940f7b704c4f8dd599455d4d2f013a297 (patch)
tree65c9141fa692262975bd2d03b092a1d54a142d97
parenta6294cd5cbd02c48b28fe8b380f8c259f14f9d8c (diff)
downloadmariadb-git-96b0404940f7b704c4f8dd599455d4d2f013a297.tar.gz
Fix for Bug#56138 "valgrind errors about overlapping memory when double-assigning same variable",
and related small fixes. mysql-test/t/user_var.test: test for bug sql/field_conv.cc: From the C standard, memcpy() has undefined behaviour if to->ptr==from->ptr sql/item_func.cc: In the case of BUG#56138, entry->value==ptr in which case memcpy() has undefined results per the C standard. sql/sql_select.cc: Work around a bug in old gcc
-rw-r--r--mysql-test/r/user_var.result3
-rw-r--r--mysql-test/t/user_var.test7
-rw-r--r--sql/field_conv.cc7
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/sql_select.cc8
5 files changed, 19 insertions, 8 deletions
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 56266a46e20..cf82a18ea83 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -447,4 +447,7 @@ IF(
count(*), 1)
1
DROP TABLE t1;
+select @v:=@v:=sum(1) from dual;
+@v:=@v:=sum(1)
+1
End of 5.1 tests
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index 4f27866de23..56217fe67d5 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -346,4 +346,11 @@ FROM t1 GROUP BY a LIMIT 1;
DROP TABLE t1;
+#
+# BUG#56138 "valgrind errors about overlapping memory when
+# double-assigning same variable"
+#
+
+select @v:=@v:=sum(1) from dual;
+
--echo End of 5.1 tests
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 0bffde9671a..a4fca6f8ad7 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -786,11 +786,8 @@ int field_conv(Field *to,Field *from)
((Field_varstring*)from)->length_bytes ==
((Field_varstring*)to)->length_bytes))
{ // Identical fields
-#ifdef HAVE_purify
- /* This may happen if one does 'UPDATE ... SET x=x' */
- if (to->ptr != from->ptr)
-#endif
- memcpy(to->ptr,from->ptr,to->pack_length());
+ // to->ptr==from->ptr may happen if one does 'UPDATE ... SET x=x'
+ memmove(to->ptr, from->ptr, to->pack_length());
return 0;
}
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index d8b5d46938e..b7afd3a624f 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -3920,7 +3920,7 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
length--; // Fix length change above
entry->value[length]= 0; // Store end \0
}
- memcpy(entry->value,ptr,length);
+ memmove(entry->value, ptr, length);
if (type == DECIMAL_RESULT)
((my_decimal*)entry->value)->fix_buffer_pointer();
entry->length= length;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 77d4447fd0f..748071986b1 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4034,8 +4034,12 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
continue;
}
-#ifdef HAVE_purify
- /* Valgrind complains about overlapped memcpy when save_pos==use. */
+#if defined(__GNUC__) && !MY_GNUC_PREREQ(4,4)
+ /*
+ Old gcc used a memcpy(), which is undefined if save_pos==use:
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19410
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39480
+ */
if (save_pos != use)
#endif
*save_pos= *use;