Index: testsuite/g++.dg/tm/pr46653.C
===================================================================
--- testsuite/g++.dg/tm/pr46653.C	(revision 0)
+++ testsuite/g++.dg/tm/pr46653.C	(revision 0)
@@ -0,0 +1,18 @@
+// { dg-do compile }
+// { dg-options "-fgnu-tm -O" }
+
+class shared_count
+{
+public:
+    volatile int j;
+  shared_count() : j(0) { }
+};
+
+shared_count * c;
+int main()
+{
+  __transaction [[atomic]] {
+    shared_count sc;
+  }
+  return 0;
+}
Index: trans-mem.c
===================================================================
--- trans-mem.c	(revision 167111)
+++ trans-mem.c	(working copy)
@@ -860,6 +860,13 @@ tm_log_eq (const void *p1, const void *p
 {
   const struct tm_log_entry *log1 = (const struct tm_log_entry *) p1;
   const struct tm_log_entry *log2 = (const struct tm_log_entry *) p2;
+
+  /* Special case plain equality because operand_equal_p() below will
+     return FALSE if the addresses are equal but they have
+     side-effects (e.g. a volatile address).  */
+  if (log1->addr == log2->addr)
+    return true;
+
   return operand_equal_p (log1->addr, log2->addr, 0);
 }
 
