summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mysql.com>2008-06-28 12:06:59 +0200
committerSergei Golubchik <serg@mysql.com>2008-06-28 12:06:59 +0200
commit97a0501e9211738d8f2fdc20f85e7a13844d1dbf (patch)
treec6c7a5f82922ef847d27521d5c6fd6a5988899ee
parent38d024b5775d233cc0e667d3c52f33cbe9017add (diff)
downloadmariadb-git-97a0501e9211738d8f2fdc20f85e7a13844d1dbf.tar.gz
fix for a strict aliasing issue with gcc 3.4.3 on sol10-amd64-a
-rw-r--r--storage/maria/trnman.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c
index b24203f4535..163305a1fb5 100644
--- a/storage/maria/trnman.c
+++ b/storage/maria/trnman.c
@@ -519,17 +519,24 @@ my_bool trnman_end_trn(TRN *trn, my_bool commit)
*/
void trnman_free_trn(TRN *trn)
{
- TRN *tmp= pool;
+ /*
+ union is to solve strict aliasing issue.
+ without it gcc 3.4.3 doesn't notice that updating *(void **)&tmp
+ modifies the value of tmp.
+ */
+ union { TRN *trn; void *v; } tmp;
+
+ tmp.trn= pool;
my_atomic_rwlock_wrlock(&LOCK_pool);
do
{
/*
- without this volatile cast gcc-3.4.4 moved the assignment
+ without this volatile cast gcc-3.4.4 moves the assignment
down after the loop at -O2
*/
- *(TRN * volatile *)&(trn->next)= tmp;
- } while (!my_atomic_casptr((void **)&pool, (void **)&tmp, trn));
+ *(TRN * volatile *)&(trn->next)= tmp.trn;
+ } while (!my_atomic_casptr((void **)&pool, &tmp.v, trn));
my_atomic_rwlock_wrunlock(&LOCK_pool);
}