diff options
Diffstat (limited to 'test/PCH')
-rw-r--r-- | test/PCH/Inputs/cxx-method.h | 3 | ||||
-rw-r--r-- | test/PCH/chain-late-anonymous-namespace.cpp | 2 | ||||
-rw-r--r-- | test/PCH/crash-12631281.cpp | 40 | ||||
-rw-r--r-- | test/PCH/cxx-constexpr.cpp | 3 | ||||
-rw-r--r-- | test/PCH/cxx-method.cpp | 6 | ||||
-rw-r--r-- | test/PCH/cxx-templates.cpp | 8 | ||||
-rw-r--r-- | test/PCH/cxx-templates.h | 49 | ||||
-rw-r--r-- | test/PCH/cxx0x-default-delete.cpp | 12 | ||||
-rw-r--r-- | test/PCH/floating-literal.c | 18 | ||||
-rw-r--r-- | test/PCH/irgen-rdar13114142.mm | 39 | ||||
-rw-r--r-- | test/PCH/macro-redef.c | 28 | ||||
-rw-r--r-- | test/PCH/missing-file.cpp | 1 | ||||
-rw-r--r-- | test/PCH/modified-header-crash.c | 5 | ||||
-rw-r--r-- | test/PCH/modified-header-error.c | 2 | ||||
-rw-r--r-- | test/PCH/multiple-include-pch.c | 18 | ||||
-rw-r--r-- | test/PCH/objc_container.m | 5 | ||||
-rw-r--r-- | test/PCH/objc_stmts.m | 10 | ||||
-rw-r--r-- | test/PCH/ocl_types.cl | 26 | ||||
-rw-r--r-- | test/PCH/ocl_types.h | 25 | ||||
-rw-r--r-- | test/PCH/thread-safety-attrs.cpp | 317 | ||||
-rw-r--r-- | test/PCH/undefined-internal.c | 15 |
21 files changed, 623 insertions, 9 deletions
diff --git a/test/PCH/Inputs/cxx-method.h b/test/PCH/Inputs/cxx-method.h index 6adb859..d5d56fe 100644 --- a/test/PCH/Inputs/cxx-method.h +++ b/test/PCH/Inputs/cxx-method.h @@ -1,6 +1,9 @@ struct S { void m(int x); + S(); + S(const S&); + operator const char*(); operator char*(); }; diff --git a/test/PCH/chain-late-anonymous-namespace.cpp b/test/PCH/chain-late-anonymous-namespace.cpp index 87205c6..edae285 100644 --- a/test/PCH/chain-late-anonymous-namespace.cpp +++ b/test/PCH/chain-late-anonymous-namespace.cpp @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -include %s -include %s -fsyntax-only %s // with PCH // RUN: %clang_cc1 -chain-include %s -chain-include %s -fsyntax-only %s +// with PCH, with modules enabled +// RUN: %clang_cc1 -chain-include %s -chain-include %s -fsyntax-only -fmodules %s #if !defined(PASS1) #define PASS1 diff --git a/test/PCH/crash-12631281.cpp b/test/PCH/crash-12631281.cpp new file mode 100644 index 0000000..f309bca --- /dev/null +++ b/test/PCH/crash-12631281.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -std=c++11 %s -emit-pch -o %t.pch +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -include-pch %t.pch -verify +// expected-no-diagnostics + +// rdar://12631281 +// This reduced test case exposed a use-after-free memory bug, which was reliable +// reproduced only on guarded malloc (and probably valgrind). + +#ifndef HEADER +#define HEADER + +template < class _T2> struct is_convertible; +template <> struct is_convertible<int> { typedef int type; }; + +template <class _T1, class _T2> struct pair { + typedef _T1 first_type; + typedef _T2 second_type; + template <class _U1, class _U2, class = typename is_convertible< first_type>::type> + pair(_U1&& , _U2&& ); // expected-note {{candidate}} +}; + +template <class _ForwardIterator> +pair<_ForwardIterator, _ForwardIterator> __equal_range(_ForwardIterator) { + return pair<_ForwardIterator, _ForwardIterator>(0, 0); // expected-error {{no matching constructor}} +} + +template <class _ForwardIterator> +pair<_ForwardIterator, _ForwardIterator> equal_range( _ForwardIterator a) { + return __equal_range(a); // expected-note {{instantiation}} +} + +class A { + pair<int, int> range() { + return equal_range(0); // expected-note {{instantiation}} + } +}; + +#else + +#endif diff --git a/test/PCH/cxx-constexpr.cpp b/test/PCH/cxx-constexpr.cpp index 8fe48f7..13f04a7 100644 --- a/test/PCH/cxx-constexpr.cpp +++ b/test/PCH/cxx-constexpr.cpp @@ -4,6 +4,9 @@ // RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t-cxx11 // RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t-cxx11 -verify %s +// RUN: %clang_cc1 -pedantic-errors -std=c++98 -emit-pch %s -o %t -fmodules +// RUN: %clang_cc1 -pedantic-errors -std=c++98 -include-pch %t -verify %s -fmodules + #ifndef HEADER_INCLUDED #define HEADER_INCLUDED diff --git a/test/PCH/cxx-method.cpp b/test/PCH/cxx-method.cpp index 40490ea..c24ad92 100644 --- a/test/PCH/cxx-method.cpp +++ b/test/PCH/cxx-method.cpp @@ -1,3 +1,4 @@ +// RUN: %clang_cc1 -x c++ -include %S/Inputs/cxx-method.h -verify %s // RUN: %clang_cc1 -x c++ -emit-pch %S/Inputs/cxx-method.h -o %t // RUN: %clang_cc1 -include-pch %t -verify %s // expected-no-diagnostics @@ -7,3 +8,8 @@ void S::m(int x) { } S::operator char *() { return 0; } S::operator const char *() { return 0; } + +struct T : S {}; + +const T a = T(); +T b(a); diff --git a/test/PCH/cxx-templates.cpp b/test/PCH/cxx-templates.cpp index d27e9ca..58c4c17 100644 --- a/test/PCH/cxx-templates.cpp +++ b/test/PCH/cxx-templates.cpp @@ -5,7 +5,7 @@ // Test with pch. // RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h // RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t -verify %s -ast-dump -o - -// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize | FileCheck %s // expected-no-diagnostics @@ -79,3 +79,9 @@ namespace TestNestedExpansion { Int &g(Int, int, double); Int &test = NestedExpansion<char, char, char>().f(0, 1, 2, Int(3), 4, 5.0); } + +namespace rdar13135282 { + void test() { + __mt_alloc<> mt = __mt_alloc<>(); + } +} diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h index 756f208..e672b0b 100644 --- a/test/PCH/cxx-templates.h +++ b/test/PCH/cxx-templates.h @@ -220,3 +220,52 @@ template<typename...A> struct NestedExpansion { template<typename...B> auto f(A...a, B...b) -> decltype(g(a + b...)); }; template struct NestedExpansion<char, char, char>; + +namespace rdar13135282 { +template < typename _Alloc > +void foo(_Alloc = _Alloc()); + +template < bool > class __pool; + +template < template < bool > class _PoolTp > +struct __common_pool { + typedef _PoolTp < 0 > pool_type; +}; + +template < template < bool > class _PoolTp > +struct __common_pool_base : __common_pool < _PoolTp > {}; + +template < template < bool > class _PoolTp > +struct A : __common_pool_base < _PoolTp > {}; + +template < typename _Poolp = A < __pool > > +struct __mt_alloc { + typedef typename _Poolp::pool_type __pool_type; + __mt_alloc() { + foo<__mt_alloc<> >(); + } +}; +} + +namespace PR13020 { +template<typename T> +void f() { + enum E { + enumerator + }; + + T t = enumerator; +} + +template void f<int>(); +} + +template<typename T> void doNotDeserialize() {} +template<typename T> struct ContainsDoNotDeserialize { + static int doNotDeserialize; +}; +template<typename T> struct ContainsDoNotDeserialize2 { + static void doNotDeserialize(); +}; +template<typename T> int ContainsDoNotDeserialize<T>::doNotDeserialize = 0; +template<typename T> void ContainsDoNotDeserialize2<T>::doNotDeserialize() {} diff --git a/test/PCH/cxx0x-default-delete.cpp b/test/PCH/cxx0x-default-delete.cpp index 39a90b8..230f6a6 100644 --- a/test/PCH/cxx0x-default-delete.cpp +++ b/test/PCH/cxx0x-default-delete.cpp @@ -20,6 +20,11 @@ class quux { ~quux() = default; }; +struct A { + A(const A&) = default; + template<typename T> A(T&&); +}; + #else foo::foo() { } // expected-error{{definition of explicitly defaulted default constructor}} @@ -31,4 +36,11 @@ void fn() { baz bz; // expected-error{{deleted function}} expected-note@16{{deleted here}} quux qx; // expected-error{{private destructor}} expected-note@20{{private here}} +struct B { A a; }; +struct C { mutable A a; }; +static_assert(__is_trivially_constructible(B, const B&), ""); +static_assert(!__is_trivially_constructible(B, B&&), ""); +static_assert(!__is_trivially_constructible(C, const C&), ""); +static_assert(!__is_trivially_constructible(C, C&&), ""); + #endif diff --git a/test/PCH/floating-literal.c b/test/PCH/floating-literal.c new file mode 100644 index 0000000..7bf10d4 --- /dev/null +++ b/test/PCH/floating-literal.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple mips64-none-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -x ast -ast-print %t | FileCheck %s + +// Make sure the semantics of FloatingLiterals are stored correctly in +// the AST. Previously, the ASTWriter didn't store anything and the +// reader assumed PPC 128-bit float semantics, which is incorrect for +// targets with 128-bit IEEE long doubles. + +long double foo = 1.0E4000L; +// CHECK: long double foo = 1.0E+4000L; + +// Just as well check the others are still sane while we're here... + +double bar = 1.0E300; +// CHECK: double bar = 1.0E+300; + +float wibble = 1.0E40; +// CHECK: float wibble = 1.0E+40; diff --git a/test/PCH/irgen-rdar13114142.mm b/test/PCH/irgen-rdar13114142.mm new file mode 100644 index 0000000..bd523c2 --- /dev/null +++ b/test/PCH/irgen-rdar13114142.mm @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 %s -emit-pch -o %t.pch +// RUN: %clang_cc1 %s -emit-llvm %s -include-pch %t.pch -o - | FileCheck %s + +#ifndef HEADER +#define HEADER + +class OOArray{ +public: + ~OOArray(); +}; + +class OOString { +public: + OOString(); + OOString(char *); +}; + +class OOPattern { +public: + OOArray matchAll(const OOString &)const { + __attribute__((__blocks__(byref))) OOArray out; + } +}; + +OOArray operator & (const OOPattern & pattern) { + pattern.matchAll(0); +} +OOArray operator & (OOString, OOString); + +#else + +// We just make sure there is no crash on IRGen (rdar://13114142) +// CHECK: _Z3foov() +void foo() { + OOString str; + str & "o"; +} + +#endif diff --git a/test/PCH/macro-redef.c b/test/PCH/macro-redef.c new file mode 100644 index 0000000..7e25d7f --- /dev/null +++ b/test/PCH/macro-redef.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 %s -emit-pch -o %t1.pch -verify +// RUN: %clang_cc1 %s -emit-pch -o %t2.pch -include-pch %t1.pch -verify +// RUN: %clang_cc1 -fsyntax-only %s -include-pch %t2.pch -verify + +// Test that a redefinition inside the PCH won't manifest as an ambiguous macro. +// rdar://13016031 + +#ifndef HEADER1 +#define HEADER1 + +#define M1 0 // expected-note {{previous}} +#define M1 1 // expected-warning {{redefined}} + +#define M2 3 + +#elif !defined(HEADER2) +#define HEADER2 + +#define M2 4 // expected-warning {{redefined}} + // expected-note@-6 {{previous}} + +#else + +// Use the error to verify it was parsed. +int x = M1; // expected-note {{previous}} +int x = M2; // expected-error {{redefinition}} + +#endif diff --git a/test/PCH/missing-file.cpp b/test/PCH/missing-file.cpp index 7dd11d4..502a9db 100644 --- a/test/PCH/missing-file.cpp +++ b/test/PCH/missing-file.cpp @@ -7,6 +7,7 @@ // %t.h might be touched by scanners as a hot file on Windows, // to fail to remove %.h with single run. +// FIXME: Do we really want to work around bugs in virus checkers here? // RUN: rm %t.h || rm %t.h || rm %t.h // Check diagnostic with location in original source: diff --git a/test/PCH/modified-header-crash.c b/test/PCH/modified-header-crash.c index c74ce22..4c21a8c 100644 --- a/test/PCH/modified-header-crash.c +++ b/test/PCH/modified-header-crash.c @@ -2,9 +2,12 @@ // RUN: cp %S/modified-header-crash.h %t.h // RUN: %clang_cc1 -DCAKE -x c-header %t.h -emit-pch -o %t -// RUN: echo >> %t.h +// RUN: echo 'int foobar;' >> %t.h // RUN: not %clang_cc1 %s -include-pch %t -fsyntax-only +// FIXME: It is intended to suppress this on win32. +// REQUIRES: ansi-escape-sequences + void f(void) { foo = 3; } diff --git a/test/PCH/modified-header-error.c b/test/PCH/modified-header-error.c index ef92494..4ad3faf 100644 --- a/test/PCH/modified-header-error.c +++ b/test/PCH/modified-header-error.c @@ -8,5 +8,5 @@ #include "header2.h" -// CHECK: fatal error: file {{.*}} has been modified since the precompiled header was built +// CHECK: fatal error: file {{.*}} has been modified since the precompiled header {{.*}} was built // REQUIRES: shell diff --git a/test/PCH/multiple-include-pch.c b/test/PCH/multiple-include-pch.c new file mode 100644 index 0000000..1ef17b9 --- /dev/null +++ b/test/PCH/multiple-include-pch.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-pch -o %t1.pch %s +// RUN: %clang_cc1 -emit-pch -o %t2.pch %s +// RUN: %clang_cc1 %s -include-pch %t1.pch -include-pch %t2.pch -verify + +#ifndef HEADER +#define HEADER + +extern int x; + +#else + +#warning parsed this +// expected-warning@-1 {{parsed this}} +int foo() { + return x; +} + +#endif diff --git a/test/PCH/objc_container.m b/test/PCH/objc_container.m index 07371ca..aafe6a9 100644 --- a/test/PCH/objc_container.m +++ b/test/PCH/objc_container.m @@ -14,9 +14,12 @@ // CHECK-PRINT: oldObject = dictionary[key]; // CHECK-PRINT: dictionary[key] = newObject; -// CHECK-IR: define void @all() nounwind +// CHECK-IR: define void @all() #0 // CHECK-IR: {{call.*objc_msgSend}} // CHECK-IR: {{call.*objc_msgSend}} // CHECK-IR: {{call.*objc_msgSend}} // CHECK-IR: {{call.*objc_msgSend}} // CHECK-IR: ret void + +// CHECK: attributes #0 = { nounwind {{.*}} } +// CHECK: attributes #1 = { nonlazybind } diff --git a/test/PCH/objc_stmts.m b/test/PCH/objc_stmts.m index b9b10c5..8deb14a 100644 --- a/test/PCH/objc_stmts.m +++ b/test/PCH/objc_stmts.m @@ -1,12 +1,12 @@ // Test this without pch. // RUN: %clang_cc1 -include %S/objc_stmts.h -emit-llvm -fobjc-exceptions -o - %s -// RUN: %clang_cc1 -include %S/objc_stmts.h -ast-dump -fobjc-exceptions -o - %s | FileCheck %s +// RUN: %clang_cc1 -include %S/objc_stmts.h -ast-print -fobjc-exceptions -o - %s | FileCheck %s // Test with pch. // RUN: %clang_cc1 -x objective-c -emit-pch -fobjc-exceptions -o %t %S/objc_stmts.h // RUN: %clang_cc1 -include-pch %t -emit-llvm -fobjc-exceptions -o - %s -// RUN: %clang_cc1 -include-pch %t -ast-dump -fobjc-exceptions -o - %s | FileCheck %s +// RUN: %clang_cc1 -include-pch %t -ast-print -fobjc-exceptions -o - %s | FileCheck %s -// CHECK: catch parm = "A *a" -// CHECK: catch parm = "B *b" -// CHECK: catch all +// CHECK: @catch(A *a) +// CHECK: @catch(B *b) +// CHECK: @catch() diff --git a/test/PCH/ocl_types.cl b/test/PCH/ocl_types.cl new file mode 100644 index 0000000..d788a32 --- /dev/null +++ b/test/PCH/ocl_types.cl @@ -0,0 +1,26 @@ +// Test this without pch. +// RUN: %clang_cc1 -include %S/ocl_types.h -fsyntax-only %s + +// Test with pch. +// RUN: %clang_cc1 -x cl -emit-pch -o %t %S/ocl_types.h +// RUN: %clang_cc1 -include-pch %t -fsyntax-only %s -ast-print + +void foo1(img1d_t img); + +void foo2(img1darr_t img); + +void foo3(img1dbuff_t img); + +void foo4(img2d_t img); + +void foo5(img2darr_t img); + +void foo6(img3d_t img); + +void foo7(smp_t smp) { + smp_t loc_smp; +} + +void foo8(evt_t evt) { + evt_t loc_evt; +} diff --git a/test/PCH/ocl_types.h b/test/PCH/ocl_types.h new file mode 100644 index 0000000..65c6acb --- /dev/null +++ b/test/PCH/ocl_types.h @@ -0,0 +1,25 @@ +/* Used with the ocl_types.cl test */ + +// image1d_t +typedef image1d_t img1d_t; + +// image1d_array_t +typedef image1d_array_t img1darr_t; + +// image1d_buffer_t +typedef image1d_buffer_t img1dbuff_t; + +// image2d_t +typedef image2d_t img2d_t; + +// image2d_array_t +typedef image2d_array_t img2darr_t; + +// image3d_t +typedef image3d_t img3d_t; + +// sampler_t +typedef sampler_t smp_t; + +// event_t +typedef event_t evt_t; diff --git a/test/PCH/thread-safety-attrs.cpp b/test/PCH/thread-safety-attrs.cpp new file mode 100644 index 0000000..a588c0e --- /dev/null +++ b/test/PCH/thread-safety-attrs.cpp @@ -0,0 +1,317 @@ +// Test this without pch. +// RUN: %clang_cc1 -include %s -fsyntax-only -verify -Wthread-safety -std=c++11 %s + +// Test with pch. +// RUN: %clang_cc1 -emit-pch -o %t %s -std=c++11 +// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify -Wthread-safety -std=c++11 %s + +#ifndef HEADER +#define HEADER + +#define LOCKABLE __attribute__ ((lockable)) +#define SCOPED_LOCKABLE __attribute__ ((scoped_lockable)) +#define GUARDED_BY(x) __attribute__ ((guarded_by(x))) +#define GUARDED_VAR __attribute__ ((guarded_var)) +#define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x))) +#define PT_GUARDED_VAR __attribute__ ((pt_guarded_var)) +#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__))) +#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__))) +#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__))) +#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__))) +#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__))) +#define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__))) +#define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__))) +#define LOCK_RETURNED(x) __attribute__ ((lock_returned(x))) +#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__))) +#define EXCLUSIVE_LOCKS_REQUIRED(...) \ + __attribute__ ((exclusive_locks_required(__VA_ARGS__))) +#define SHARED_LOCKS_REQUIRED(...) \ + __attribute__ ((shared_locks_required(__VA_ARGS__))) +#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis)) + + +class __attribute__((lockable)) Mutex { + public: + void Lock() __attribute__((exclusive_lock_function)); + void ReaderLock() __attribute__((shared_lock_function)); + void Unlock() __attribute__((unlock_function)); + bool TryLock() __attribute__((exclusive_trylock_function(true))); + bool ReaderTryLock() __attribute__((shared_trylock_function(true))); + void LockWhen(const int &cond) __attribute__((exclusive_lock_function)); +}; + +class __attribute__((scoped_lockable)) MutexLock { + public: + MutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu))); + ~MutexLock() __attribute__((unlock_function)); +}; + +class __attribute__((scoped_lockable)) ReaderMutexLock { + public: + ReaderMutexLock(Mutex *mu) __attribute__((exclusive_lock_function(mu))); + ~ReaderMutexLock() __attribute__((unlock_function)); +}; + +class SCOPED_LOCKABLE ReleasableMutexLock { + public: + ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu); + ~ReleasableMutexLock() UNLOCK_FUNCTION(); + + void Release() UNLOCK_FUNCTION(); +}; + + +// The universal lock, written "*", allows checking to be selectively turned +// off for a particular piece of code. +void beginNoWarnOnReads() SHARED_LOCK_FUNCTION("*"); +void endNoWarnOnReads() UNLOCK_FUNCTION("*"); +void beginNoWarnOnWrites() EXCLUSIVE_LOCK_FUNCTION("*"); +void endNoWarnOnWrites() UNLOCK_FUNCTION("*"); + + +// For testing handling of smart pointers. +template<class T> +class SmartPtr { +public: + SmartPtr(T* p) : ptr_(p) { } + SmartPtr(const SmartPtr<T>& p) : ptr_(p.ptr_) { } + ~SmartPtr(); + + T* get() const { return ptr_; } + T* operator->() const { return ptr_; } + T& operator*() const { return *ptr_; } + +private: + T* ptr_; +}; + + +// For testing destructor calls and cleanup. +class MyString { +public: + MyString(const char* s); + ~MyString(); +}; + + + +Mutex sls_mu; + +Mutex sls_mu2 __attribute__((acquired_after(sls_mu))); +int sls_guard_var __attribute__((guarded_var)) = 0; +int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0; + +bool getBool(); + +class MutexWrapper { +public: + Mutex mu; + int x __attribute__((guarded_by(mu))); + void MyLock() __attribute__((exclusive_lock_function(mu))); +}; + +#else + +MutexWrapper sls_mw; + +void sls_fun_0() { + sls_mw.mu.Lock(); + sls_mw.x = 5; + sls_mw.mu.Unlock(); +} + +void sls_fun_2() { + sls_mu.Lock(); + int x = sls_guard_var; + sls_mu.Unlock(); +} + +void sls_fun_3() { + sls_mu.Lock(); + sls_guard_var = 2; + sls_mu.Unlock(); +} + +void sls_fun_4() { + sls_mu2.Lock(); + sls_guard_var = 2; + sls_mu2.Unlock(); +} + +void sls_fun_5() { + sls_mu.Lock(); + int x = sls_guardby_var; + sls_mu.Unlock(); +} + +void sls_fun_6() { + sls_mu.Lock(); + sls_guardby_var = 2; + sls_mu.Unlock(); +} + +void sls_fun_7() { + sls_mu.Lock(); + sls_mu2.Lock(); + sls_mu2.Unlock(); + sls_mu.Unlock(); +} + +void sls_fun_8() { + sls_mu.Lock(); + if (getBool()) + sls_mu.Unlock(); + else + sls_mu.Unlock(); +} + +void sls_fun_9() { + if (getBool()) + sls_mu.Lock(); + else + sls_mu.Lock(); + sls_mu.Unlock(); +} + +void sls_fun_good_6() { + if (getBool()) { + sls_mu.Lock(); + } else { + if (getBool()) { + getBool(); // EMPTY + } else { + getBool(); // EMPTY + } + sls_mu.Lock(); + } + sls_mu.Unlock(); +} + +void sls_fun_good_7() { + sls_mu.Lock(); + while (getBool()) { + sls_mu.Unlock(); + if (getBool()) { + if (getBool()) { + sls_mu.Lock(); + continue; + } + } + sls_mu.Lock(); + } + sls_mu.Unlock(); +} + +void sls_fun_good_8() { + sls_mw.MyLock(); + sls_mw.mu.Unlock(); +} + +void sls_fun_bad_1() { + sls_mu.Unlock(); // \ + // expected-warning{{unlocking 'sls_mu' that was not locked}} +} + +void sls_fun_bad_2() { + sls_mu.Lock(); + sls_mu.Lock(); // \ + // expected-warning{{locking 'sls_mu' that is already locked}} + sls_mu.Unlock(); +} + +void sls_fun_bad_3() { + sls_mu.Lock(); // expected-note {{mutex acquired here}} +} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}} + +void sls_fun_bad_4() { + if (getBool()) + sls_mu.Lock(); // expected-note{{mutex acquired here}} + else + sls_mu2.Lock(); // expected-note{{mutex acquired here}} +} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} \ + // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}} + +void sls_fun_bad_5() { + sls_mu.Lock(); // expected-note {{mutex acquired here}} + if (getBool()) + sls_mu.Unlock(); +} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} + +void sls_fun_bad_6() { + if (getBool()) { + sls_mu.Lock(); // expected-note {{mutex acquired here}} + } else { + if (getBool()) { + getBool(); // EMPTY + } else { + getBool(); // EMPTY + } + } + sls_mu.Unlock(); // \ + expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\ + expected-warning{{unlocking 'sls_mu' that was not locked}} +} + +void sls_fun_bad_7() { + sls_mu.Lock(); + while (getBool()) { + sls_mu.Unlock(); + if (getBool()) { + if (getBool()) { + continue; // \ + expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} + } + } + sls_mu.Lock(); // expected-note {{mutex acquired here}} + } + sls_mu.Unlock(); +} + +void sls_fun_bad_8() { + sls_mu.Lock(); // expected-note{{mutex acquired here}} + + do { + sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} + } while (getBool()); +} + +void sls_fun_bad_9() { + do { + sls_mu.Lock(); // \ + // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \ + // expected-note{{mutex acquired here}} + } while (getBool()); + sls_mu.Unlock(); +} + +void sls_fun_bad_10() { + sls_mu.Lock(); // expected-note 2{{mutex acquired here}} + while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} + sls_mu.Unlock(); + } +} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}} + +void sls_fun_bad_11() { + while (getBool()) { // \ + expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} + sls_mu.Lock(); // expected-note {{mutex acquired here}} + } + sls_mu.Unlock(); // \ + // expected-warning{{unlocking 'sls_mu' that was not locked}} +} + +void sls_fun_bad_12() { + sls_mu.Lock(); // expected-note {{mutex acquired here}} + while (getBool()) { + sls_mu.Unlock(); + if (getBool()) { + if (getBool()) { + break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} + } + } + sls_mu.Lock(); + } + sls_mu.Unlock(); +} + +#endif diff --git a/test/PCH/undefined-internal.c b/test/PCH/undefined-internal.c new file mode 100644 index 0000000..ef51460 --- /dev/null +++ b/test/PCH/undefined-internal.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-pch %s -o %t +// RUN: %clang_cc1 -include-pch %t %s -verify +#ifndef HEADER_H +#define HEADER_H +static void f(); +static void g(); +void h() { + f(); + g(); +} +#else +static void g() {} +// expected-warning@5{{function 'f' has internal linkage but is not defined}} +// expected-note@8{{used here}} +#endif |