===================================================================
@@ -1,5 +1,8 @@
-// Regression test for bugfix, where shared locks are not properly
-// removed from locksets if a "universal lock" is present.
+// Regression test for two bugfixes.
+// Bugfix 1: Shared locks are not properly removed from locksets
+// if a "universal lock" is present.
+// Bugfix 2: Canonicalization does not properly store the lock in
+// the hash table if the lock function is attached to a base class.
// { dg-do compile }
// { dg-options "-Wthread-safety" }
@@ -7,6 +10,7 @@
class Foo;
+/* Bugfix 1 */
class Bar {
public:
Foo* foo;
@@ -29,3 +33,23 @@ void Bar::bar() {
ReaderMutexLock rlock(&mu_);
}
+
+/* Bugfix 2 */
+class LOCKABLE Base {
+public:
+ Mutex mu_;
+
+ void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.Lock(); }
+ void Unlock() UNLOCK_FUNCTION() { mu_.Unlock(); }
+};
+
+class Derived : public Base {
+public:
+ int b;
+};
+
+void doSomething(Derived *d) {
+ d->Lock();
+ d->Unlock();
+};
+
===================================================================
@@ -927,7 +927,16 @@ get_canonical_lock_expr (tree lock, tree base_obj,
NULL_TREE);
if (lang_hooks.decl_is_base_field (component))
- return canon_base;
+ {
+ if (is_temp_expr)
+ return canon_base;
+ else
+ /* return canon_base, but recalculate it so that it is stored
+ in the hash table. */
+ return get_canonical_lock_expr (base, base_obj,
+ false /* is_temp_expr */,
+ new_leftmost_base_var);
+ }
if (base != canon_base)
lock = build3 (COMPONENT_REF, TREE_TYPE (component),