diff options
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/SemaTemplate/attributes.cpp | 11 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/warn-thread-safety-analysis.cpp | 30 |
2 files changed, 41 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/attributes.cpp b/clang/test/SemaTemplate/attributes.cpp index 1d46058b019..7634b937c90 100644 --- a/clang/test/SemaTemplate/attributes.cpp +++ b/clang/test/SemaTemplate/attributes.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -verify %s +// RUN: not %clang_cc1 -std=gnu++11 -ast-dump %s | FileCheck %s namespace attribute_aligned { template<int N> @@ -52,3 +53,13 @@ namespace PR9049 { template<typename T> inline void WBCFRelease(__attribute__((cf_consumed)) T aValue) { if(aValue) CFRelease(aValue); } } + +// CHECK: FunctionTemplateDecl {{.*}} HasAnnotations +// CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR" +// CHECK: AnnotateAttr {{.*}} "ANNOTATE_FOO" +// CHECK: FunctionDecl {{.*}} HasAnnotations +// CHECK: TemplateArgument type 'int' +// CHECK: AnnotateAttr {{.*}} "ANNOTATE_BAR" +// CHECK: AnnotateAttr {{.*}} "ANNOTATE_FOO" +template<typename T> [[clang::annotate("ANNOTATE_FOO"), clang::annotate("ANNOTATE_BAR")]] void HasAnnotations(); +void UseAnnotations() { HasAnnotations<int>(); } diff --git a/clang/test/SemaTemplate/warn-thread-safety-analysis.cpp b/clang/test/SemaTemplate/warn-thread-safety-analysis.cpp new file mode 100644 index 00000000000..03bae7a2925 --- /dev/null +++ b/clang/test/SemaTemplate/warn-thread-safety-analysis.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -std=c++11 %s -verify -Wthread-safety-analysis + +class Mutex { +public: + void Lock() __attribute__((exclusive_lock_function())); + void Unlock() __attribute__((unlock_function())); +}; + +class A { +public: + Mutex mu1, mu2; + + void foo() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {} + + template <class T> void bar() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) { + foo(); + } +}; + +void f() { + A a; + a.mu1.Lock(); + a.mu2.Lock(); + a.bar<int>(); + a.mu2.Unlock(); + a.bar<int>(); // expected-warning {{calling function 'bar' requires holding mutex 'a.mu2' exclusively}} + a.mu1.Unlock(); + a.bar<int>(); // expected-warning {{calling function 'bar' requires holding mutex 'a.mu1' exclusively}} \ + expected-warning {{calling function 'bar' requires holding mutex 'a.mu2' exclusively}} +} |

