This patch fixes an error where Annotalysis generates bogus warnings when using lock and unlock functions that are attached to a base class. The canonicalize routine did not work correctly in this case.
Bootstrapped and passed gcc regression testsuite on x86_64-unknown-linux-gnu. Okay for google/gcc-4_6? -DeLesley Changelog.google-4_6: 2011-10-11 DeLesley Hutchins <deles...@google.com> * tree-threadsafe-analyze.c (get_canonical_lock_expr) testsuite/Changelog.google-4_6: 2011-10-11 DeLesley Hutchins <deles...@google.com> * g++.dg/thread-ann/thread_annot_lock-83.C Index: gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-83.C =================================================================== --- gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-83.C (revision 0) +++ gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-83.C (revision 0) @@ -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(); +}; + Index: gcc/tree-threadsafe-analyze.c =================================================================== --- gcc/tree-threadsafe-analyze.c (revision 179771) +++ gcc/tree-threadsafe-analyze.c (working copy) @@ -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), -- DeLesley Hutchins | Software Engineer | deles...@google.com | 505-206-0315