aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann')
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_common.h47
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-50.C22
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-51.C44
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-52.C39
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-53.C40
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-54.C35
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-55.C38
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-56.C36
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-57.C22
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-58.C32
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-59.C34
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-60.C37
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-61.C15
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-62.C18
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-65.C30
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-66.C35
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-67.C32
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-68.C34
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-69.C31
-rw-r--r--gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-70.C38
20 files changed, 659 insertions, 0 deletions
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_common.h b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_common.h
index 192c84e84..a21af97fe 100644
--- a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_common.h
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_common.h
@@ -27,6 +27,11 @@
#define SHARED_LOCKS_REQUIRED(...) \
__attribute__ ((shared_locks_required(__VA_ARGS__)))
#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))
+#define IGNORE_READS_BEGIN __attribute__ ((ignore_reads_begin))
+#define IGNORE_READS_END __attribute__ ((ignore_reads_end))
+#define IGNORE_WRITES_BEGIN __attribute__ ((ignore_writes_begin))
+#define IGNORE_WRITES_END __attribute__ ((ignore_writes_end))
+#define UNPROTECTED_READ __attribute__ ((unprotected_read))
#else
@@ -48,6 +53,11 @@
#define EXCLUSIVE_LOCKS_REQUIRED(...)
#define SHARED_LOCKS_REQUIRED(...)
#define NO_THREAD_SAFETY_ANALYSIS
+#define IGNORE_READS_BEGIN
+#define IGNORE_READS_END
+#define IGNORE_WRITES_BEGIN
+#define IGNORE_WRITES_END
+#define UNPROTECTED_READ
#endif // defined(__GNUC__) && defined(__SUPPORT_TS_ANNOTATION__)
@@ -81,4 +91,41 @@ class SCOPED_LOCKABLE ReleasableMutexLock {
void Release() UNLOCK_FUNCTION();
};
+void AnnotateIgnoreReadsBegin(const char *file, int line) IGNORE_READS_BEGIN;
+void AnnotateIgnoreReadsEnd(const char *file, int line) IGNORE_READS_END;
+void AnnotateIgnoreWritesBegin(const char *file, int line) IGNORE_WRITES_BEGIN;
+void AnnotateIgnoreWritesEnd(const char *file, int line) IGNORE_WRITES_END;
+
+#define ANNOTATE_IGNORE_READS_BEGIN() \
+ AnnotateIgnoreReadsBegin(__FILE__, __LINE__)
+
+#define ANNOTATE_IGNORE_READS_END() \
+ AnnotateIgnoreReadsEnd(__FILE__, __LINE__)
+
+#define ANNOTATE_IGNORE_WRITES_BEGIN() \
+ AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
+
+#define ANNOTATE_IGNORE_WRITES_END() \
+ AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
+
+#define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
+ do { \
+ ANNOTATE_IGNORE_READS_BEGIN(); \
+ ANNOTATE_IGNORE_WRITES_BEGIN(); \
+ }while(0) \
+
+#define ANNOTATE_IGNORE_READS_AND_WRITES_END() \
+ do { \
+ ANNOTATE_IGNORE_WRITES_END(); \
+ ANNOTATE_IGNORE_READS_END(); \
+ }while(0) \
+
+template <class T>
+inline T ANNOTATE_UNPROTECTED_READ(const T &x) UNPROTECTED_READ {
+ ANNOTATE_IGNORE_READS_BEGIN();
+ T res = x;
+ ANNOTATE_IGNORE_READS_END();
+ return res;
+}
+
#endif // THREAD_ANNOT_COMMON_H
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-50.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-50.C
new file mode 100644
index 000000000..e1e24c18e
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-50.C
@@ -0,0 +1,22 @@
+// Test the support for allowing non-const but non-modifying methods to be
+// protected by reader locks.
+// This is a good test case. (i.e. There should be no warning emitted by the
+// compiler.)
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include <map>
+#include "thread_annot_common.h"
+
+typedef std::map<int, int> MyMapType;
+
+Mutex mu;
+MyMapType MyMap GUARDED_BY(mu);
+
+int foo(int key) {
+ ReaderMutexLock l(&mu);
+ MyMapType::const_iterator iter = MyMap.find(key);
+ if (iter != MyMap.end()) {
+ return iter->second;
+ }
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-51.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-51.C
new file mode 100644
index 000000000..400c81e82
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-51.C
@@ -0,0 +1,44 @@
+// Test the support for allowing non-const but non-modifying methods to be
+// protected by reader locks.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+class Foo {
+ public:
+ int GetVal1(int a) const {
+ return a + val1;
+ }
+
+ int GetVal1(int a) {
+ return a + val1;
+ }
+
+ int GetVal1(int a, float b) {
+ return a + b + val1;
+ }
+
+ int GetVal2(int a) {
+ return a + val2;
+ }
+
+ int GetVal2(float a) {
+ return val2;
+ }
+
+
+ private:
+ int val1;
+ int val2;
+};
+
+Mutex mu;
+Foo foo GUARDED_BY(mu);
+
+int main() {
+ mu.ReaderLock();
+ int x = foo.GetVal1(3); // should not warn
+ int y = foo.GetVal2(3); // { dg-warning "Writing to variable" }
+ mu.Unlock();
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-52.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-52.C
new file mode 100644
index 000000000..5535034b0
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-52.C
@@ -0,0 +1,39 @@
+// Test the support for use of point_to_guarded{_by} on smart/scoped pointers.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+template<class T>
+class scoped_ptr {
+ public:
+ typedef T element_type;
+
+ explicit scoped_ptr(T * p = 0);
+ ~scoped_ptr();
+
+ void reset(T * p = 0);
+
+ T & operator*() const;
+ T * operator->() const;
+ T * get() const;
+};
+
+class Foo {
+ public:
+ int x;
+};
+
+Mutex mu1, mu2;
+scoped_ptr<int> a PT_GUARDED_BY(mu1);
+scoped_ptr<Foo> b GUARDED_BY(mu2) PT_GUARDED_VAR;
+
+main()
+{
+ *a = 5; // { dg-warning "Access to memory location pointed to" }
+ a.reset();
+ b->x = 3 + *a; // { dg-warning "Reading variable" }
+}
+
+// { dg-warning "Access to memory location pointed to by variable 'b'" "" { target *-*-* } 35 }
+// { dg-warning "Access to memory location pointed to by variable 'a'" "" { target *-*-* } 35 }
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-53.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-53.C
new file mode 100644
index 000000000..0c03d77d9
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-53.C
@@ -0,0 +1,40 @@
+// Test the support for use of point_to_guarded{_by} on smart/scoped pointers.
+// This is a good test case. (i.e. There should be no warning emitted by the
+// compiler.)
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+template<class T>
+class scoped_ptr {
+ public:
+ typedef T element_type;
+
+ explicit scoped_ptr(T * p = 0);
+ ~scoped_ptr();
+
+ void reset(T * p = 0);
+
+ T & operator*() const;
+ T * operator->() const;
+ T * get() const;
+};
+
+class Foo {
+ public:
+ int x;
+};
+
+Mutex mu1, mu2;
+scoped_ptr<int> a PT_GUARDED_BY(mu1);
+scoped_ptr<Foo> b GUARDED_BY(mu2) PT_GUARDED_VAR;
+
+main()
+{
+ MutexLock l1(&mu1);
+ MutexLock l2(&mu2);
+ *a = 5;
+ a.reset();
+ b->x = 3 + *a;
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-54.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-54.C
new file mode 100644
index 000000000..e90652407
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-54.C
@@ -0,0 +1,35 @@
+// Test the handling of the annotations with function parameters.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+class Base {
+ private:
+ Mutex mu1_;
+
+ public:
+ Mutex *mutable_mu() LOCK_RETURNED(mu1_) { return &mu1_; }
+};
+
+class Foo {
+ public:
+ Mutex mu2_;
+ void Test1(Mutex* mu) const EXCLUSIVE_LOCKS_REQUIRED(mu, mu2_);
+ void Test2(Mutex* mu) const LOCKS_EXCLUDED(mu);
+};
+
+class Bar : public Base {
+ private:
+ Foo foo_;
+
+ public:
+ void Test3();
+};
+
+void Bar::Test3() {
+ mutable_mu()->Lock();
+ foo_.Test1(mutable_mu()); // { dg-warning "Calling function" }
+ foo_.Test2(mutable_mu()); // { dg-warning "Cannot call function" }
+ mutable_mu()->Unlock();
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-55.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-55.C
new file mode 100644
index 000000000..10a12d43e
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-55.C
@@ -0,0 +1,38 @@
+// Test the handling of the annotations with function parameters.
+// This is a good test case. (i.e. There should be no warning emitted by the
+// compiler.)
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+class Base {
+ private:
+ Mutex mu1_;
+
+ public:
+ Mutex *mutable_mu() LOCK_RETURNED(mu1_) { return &mu1_; }
+};
+
+class Foo {
+ public:
+ Mutex mu2_;
+ void Test1(Mutex* mu) const EXCLUSIVE_LOCKS_REQUIRED(mu, mu2_);
+ void Test2(Mutex* mu) const LOCKS_EXCLUDED(mu);
+};
+
+class Bar : public Base {
+ private:
+ Foo foo_;
+
+ public:
+ void Test3();
+};
+
+void Bar::Test3() {
+ MutexLock l(&foo_.mu2_);
+ mutable_mu()->Lock();
+ foo_.Test1(mutable_mu());
+ mutable_mu()->Unlock();
+ foo_.Test2(mutable_mu());
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-56.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-56.C
new file mode 100644
index 000000000..71221eb5f
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-56.C
@@ -0,0 +1,36 @@
+// Test the handling of a method with lock annotations accessed through a
+// smart/scoped pointer.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+template<class T>
+class scoped_ptr {
+ public:
+ typedef T element_type;
+
+ explicit scoped_ptr(T * p = 0);
+ ~scoped_ptr();
+
+ void reset(T * p = 0);
+
+ T & operator*() const;
+ T * operator->() const;
+ T * get() const;
+};
+
+class LOCKABLE Foo {
+ public:
+ Mutex *mutex_;
+ int x;
+ int GetValue() EXCLUSIVE_LOCKS_REQUIRED(mutex);
+};
+
+scoped_ptr<Foo> b;
+
+main()
+{
+ int a;
+ a = b->GetValue(); // { dg-warning "Calling function 'GetValue' requires" }
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-57.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-57.C
new file mode 100644
index 000000000..a12150436
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-57.C
@@ -0,0 +1,22 @@
+// Test handling of arguments passed to reference parameters.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+struct Foo {
+ int a;
+};
+
+void func1(Foo &f);
+
+void func2(Foo *f);
+
+Mutex mu;
+
+Foo foo GUARDED_BY(mu);
+
+main() {
+ func1(foo); // { dg-warning "Reading variable 'foo' requires lock" }
+ func2(&foo); // should not warn
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-58.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-58.C
new file mode 100644
index 000000000..858e63558
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-58.C
@@ -0,0 +1,32 @@
+// Test handling of arguments passed to reference parameters.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include <string>
+#include "thread_annot_common.h"
+
+class Base {
+ public:
+ Base() {}
+ protected:
+ Mutex* mutex() const LOCK_RETURNED(mutex_) { return &mutex_; }
+ private:
+ mutable Mutex mutex_;
+};
+
+class Subclass : public Base {
+ public:
+ Subclass() {}
+
+ void ClearValue() { SetValueLocked(0); }
+ std::string GetValue() const;
+
+ private:
+ void SetValueLocked(std::string value) { value_ = value; }
+
+ std::string value_ GUARDED_BY(mutex_);
+};
+
+std::string Subclass::GetValue() const {
+ return value_; // { dg-warning "Reading variable 'value_' requires lock" }
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-59.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-59.C
new file mode 100644
index 000000000..158c940e2
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-59.C
@@ -0,0 +1,34 @@
+// Test handling of additional (finer-grained) escape hatche attributes.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+Mutex *mu1, *mu2;
+
+struct Foo {
+ int a GUARDED_BY(mu1);
+};
+
+int x GUARDED_BY(mu1) = 1;
+int y GUARDED_BY(mu2);
+
+main() {
+ int z;
+ Foo w;
+ ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
+ y = x + 1;
+ x = y;
+ ANNOTATE_IGNORE_READS_AND_WRITES_END();
+
+ z = ANNOTATE_UNPROTECTED_READ(w.a) + 1;
+ if (z > 1) {
+ ANNOTATE_IGNORE_READS_BEGIN();
+ z = x + 2;
+ }
+ else {
+ ANNOTATE_IGNORE_READS_BEGIN();
+ z = x + 1;
+ }
+ z = y;
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-60.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-60.C
new file mode 100644
index 000000000..099aa8290
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-60.C
@@ -0,0 +1,37 @@
+// Test handling of additional (finer-grained) escape hatche attributes.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+Mutex *mu1, *mu2;
+
+struct Foo {
+ int a GUARDED_BY(mu1);
+};
+
+int x GUARDED_BY(mu1) = 1;
+int y GUARDED_BY(mu2);
+
+main() {
+ int z;
+ Foo w;
+ ANNOTATE_IGNORE_READS_BEGIN();
+ y = x + 1; // { dg-warning "Writing to variable 'y' requires lock" }
+ x = y; // { dg-warning "Writing to variable 'x' requires lock" }
+ ANNOTATE_IGNORE_READS_END();
+ ANNOTATE_IGNORE_WRITES_BEGIN();
+ y = x + 1; // { dg-warning "Reading variable 'x' requires lock" }
+ x = y; // { dg-warning "Reading variable 'y' requires lock" }
+ ANNOTATE_IGNORE_WRITES_END();
+
+ z = w.a + 1; // { dg-warning "Reading variable 'w.a' requires lock" }
+ if (z > 1) {
+ z = x + 2; // { dg-warning "Reading variable 'x' requires lock" }
+ }
+ else {
+ ANNOTATE_IGNORE_READS_BEGIN();
+ z = x + 1;
+ }
+ z = y; // { dg-warning "Reading variable 'y' requires lock" }
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-61.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-61.C
new file mode 100644
index 000000000..11f6308eb
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-61.C
@@ -0,0 +1,15 @@
+// Test the fix for a bug introduced by the support of pass-by-reference
+// paramters.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+struct Foo { Foo & operator<< (bool) {} };
+struct Bar { Foo & func () {} };
+struct Bas { void operator& (Foo &) {} };
+void mumble()
+{
+ Bas() & Bar().func() << "" << "";
+ Bas() & Bar().func() << "";
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-62.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-62.C
new file mode 100644
index 000000000..95f318699
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-62.C
@@ -0,0 +1,18 @@
+// Test the support for allowing non-const but non-modifying overloaded
+// operator to be protected by reader locks.
+// This is a good test case. (i.e. There should be no warning emitted by the
+// compiler.)
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include <vector>
+#include "thread_annot_common.h"
+
+Mutex mu;
+
+std::vector<int> counts GUARDED_BY(mu);
+
+int foo(int key) {
+ ReaderMutexLock l(&mu);
+ return counts[key];
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-65.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-65.C
new file mode 100644
index 000000000..d129fc94c
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-65.C
@@ -0,0 +1,30 @@
+// Test the fix for a bug in the support of allowing reader locks for
+// non-const, non-modifying overload functions. (We didn't handle the builtin
+// properly.)
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+enum MyFlags {
+ Zero,
+ One,
+ Two,
+ Three,
+ Four,
+ Five,
+ Six,
+ Seven,
+ Eight,
+ Nine
+};
+
+inline MyFlags
+operator|(MyFlags a, MyFlags b)
+{
+ return MyFlags(static_cast<int>(a) | static_cast<int>(b));
+}
+
+inline MyFlags&
+operator|=(MyFlags& a, MyFlags b)
+{
+ return a = a | b;
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-66.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-66.C
new file mode 100644
index 000000000..c341973e7
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-66.C
@@ -0,0 +1,35 @@
+// Test annotations on out-of-line definitions of member functions where the
+// annotations refer to locks that are also data members in the class.
+// This is a good test case. (i.e. There should be no warning emitted by the
+// compiler.)
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+Mutex mu;
+
+class Foo {
+ public:
+ int method1(int i);
+ int data GUARDED_BY(mu1);
+ Mutex *mu1;
+ Mutex *mu2;
+};
+
+int Foo::method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2)
+{
+ return data + i;
+}
+
+main()
+{
+ Foo a;
+
+ MutexLock l(a.mu2);
+ a.mu1->Lock();
+ mu.Lock();
+ a.method1(1);
+ mu.Unlock();
+ a.mu1->Unlock();
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-67.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-67.C
new file mode 100644
index 000000000..be228ec20
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-67.C
@@ -0,0 +1,32 @@
+// Test annotations on out-of-line definitions of member functions where the
+// annotations refer to locks that are also data members in the class.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+Mutex mu;
+
+class Foo {
+ public:
+ int method1(int i);
+ int data GUARDED_BY(mu1);
+ Mutex *mu1;
+ Mutex *mu2;
+};
+
+int Foo::method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3)
+{
+ return data + i;
+}
+
+main()
+{
+ Foo a;
+
+ a.method1(1); // { dg-warning "Calling function 'method1' requires lock" }
+}
+
+// { dg-warning "Calling function 'method1' requires lock 'mu'" { target *-*-* } 27 }
+// { dg-warning "Calling function 'method1' requires lock 'a.mu2'" { target *-*-* } 27 }
+// { dg-warning "Calling function 'method1' requires lock 'mu3'" { target *-*-* } 27 }
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-68.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-68.C
new file mode 100644
index 000000000..95e8d6908
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-68.C
@@ -0,0 +1,34 @@
+// Test a fix to a bug in the delayed name binding with nested template
+// instantiation. We use a stack to make sure a name is not resolved to an
+// inner context.
+// This is a good test case. (i.e. There should be no warning emitted by the
+// compiler.)
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+template <typename T>
+class Bar {
+ Mutex mu_;
+};
+
+template <typename T>
+class Foo {
+ public:
+ void func(T x) {
+ MutexLock l(&mu_);
+ count_ = x;
+ }
+
+ private:
+ T count_ GUARDED_BY(mu_);
+ Bar<T> bar_;
+ Mutex mu_;
+};
+
+int main()
+{
+ Foo<int> *foo;
+ foo->func(5);
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-69.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-69.C
new file mode 100644
index 000000000..478e8b273
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-69.C
@@ -0,0 +1,31 @@
+// Test a fix to a bug in the delayed name binding with nested template
+// instantiation. We use a stack to make sure a name is not resolved to an
+// inner context.
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+template <typename T>
+class Bar {
+ Mutex mu_;
+};
+
+template <typename T>
+class Foo {
+ public:
+ void func(T x) {
+ count_ = x; // { dg-warning "Writing to variable 'count_' requires lock" }
+ }
+
+ private:
+ T count_ GUARDED_BY(mu_);
+ Bar<T> bar_;
+ Mutex mu_;
+};
+
+int main()
+{
+ Foo<int> *foo;
+ foo->func(5);
+}
diff --git a/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-70.C b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-70.C
new file mode 100644
index 000000000..782d13af4
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/g++.dg/thread-ann/thread_annot_lock-70.C
@@ -0,0 +1,38 @@
+// Test a fix to a bug when handling calls to virtual functions that are
+// annotated with LOCK/UNLOCK_FUNCTION. More specifically, the bug happens
+// when we tried to assert the function decl of a gimple call statement
+// returned by gimple_call_fndecl is non-NULL, which is not true when the call
+// is a virtual function call. Instead, we should either get the function decl
+// through the reference object, or (as is the fix) simply pass the function
+// decl that we have extracted earlier all the way to
+// handle_lock_primitive_attrs where the assertion fails.
+//
+// This is a good test case. (i.e. There should be no error/warning/ICE
+// triggered.)
+//
+// { dg-do compile }
+// { dg-options "-Wthread-safety -O" }
+
+#include "thread_annot_common.h"
+
+class Base {
+ protected:
+ virtual void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_) { mu_.Lock(); }
+ virtual void Unlock() UNLOCK_FUNCTION(mu_) { mu_.Unlock(); }
+ Mutex mu_;
+};
+
+class Child: public Base {
+ int a;
+ public:
+ void func1() {
+ Lock();
+ a += 1;
+ Unlock();
+ }
+};
+
+main() {
+ Child c;
+ c.func1();
+}