aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX')
-rw-r--r--test/SemaCXX/MicrosoftCompatibility.cpp4
-rw-r--r--test/SemaCXX/MicrosoftCompatibilityNoExceptions.cpp8
-rw-r--r--test/SemaCXX/PR10243.cpp4
-rw-r--r--test/SemaCXX/abstract.cpp14
-rw-r--r--test/SemaCXX/address-of-temporary.cpp40
-rw-r--r--test/SemaCXX/alias-template.cpp27
-rw-r--r--test/SemaCXX/altivec.cpp7
-rw-r--r--test/SemaCXX/anonymous-union-cxx11.cpp13
-rw-r--r--test/SemaCXX/array-bound-merge.cpp2
-rw-r--r--test/SemaCXX/arrow-operator.cpp28
-rw-r--r--test/SemaCXX/attr-deprecated.cpp42
-rw-r--r--test/SemaCXX/attr-visibility.cpp20
-rw-r--r--test/SemaCXX/bool.cpp2
-rw-r--r--test/SemaCXX/condition.cpp2
-rw-r--r--test/SemaCXX/conditional-expr.cpp26
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp130
-rw-r--r--test/SemaCXX/constant-expression.cpp9
-rw-r--r--test/SemaCXX/constexpr-many-arguments.cpp42
-rw-r--r--test/SemaCXX/constructor-initializer.cpp13
-rw-r--r--test/SemaCXX/conversion-function.cpp11
-rw-r--r--test/SemaCXX/conversion.cpp60
-rw-r--r--test/SemaCXX/crashes.cpp32
-rw-r--r--test/SemaCXX/cxx0x-cursory-default-delete.cpp21
-rw-r--r--test/SemaCXX/cxx0x-defaulted-functions.cpp110
-rw-r--r--test/SemaCXX/cxx0x-initializer-aggregates.cpp29
-rw-r--r--test/SemaCXX/cxx0x-initializer-constructor.cpp23
-rw-r--r--test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp12
-rw-r--r--test/SemaCXX/cxx98-compat-pedantic.cpp2
-rw-r--r--test/SemaCXX/cxx98-compat.cpp61
-rw-r--r--test/SemaCXX/dcl_ambig_res.cpp6
-rw-r--r--test/SemaCXX/dcl_init_aggr.cpp2
-rw-r--r--test/SemaCXX/decl-expr-ambiguity.cpp33
-rw-r--r--test/SemaCXX/default1.cpp9
-rw-r--r--test/SemaCXX/deleted-function.cpp10
-rw-r--r--test/SemaCXX/deleted-operator.cpp4
-rw-r--r--test/SemaCXX/elaborated-type-specifier.cpp7
-rw-r--r--test/SemaCXX/enum-scoped.cpp7
-rw-r--r--test/SemaCXX/expressions.cpp2
-rw-r--r--test/SemaCXX/format-strings-0x.cpp12
-rw-r--r--test/SemaCXX/function-extern-c.cpp2
-rw-r--r--test/SemaCXX/function-redecl.cpp28
-rw-r--r--test/SemaCXX/implicit-exception-spec.cpp17
-rw-r--r--test/SemaCXX/invalid-member-expr.cpp31
-rw-r--r--test/SemaCXX/lambda-expressions.cpp141
-rw-r--r--test/SemaCXX/literal-operators.cpp1
-rw-r--r--test/SemaCXX/long-virtual-inheritance-chain.cpp53
-rw-r--r--test/SemaCXX/member-expr.cpp10
-rw-r--r--test/SemaCXX/member-init.cpp4
-rw-r--r--test/SemaCXX/member-operator-expr.cpp5
-rw-r--r--test/SemaCXX/microsoft-cxx0x.cpp14
-rw-r--r--test/SemaCXX/neon-vector-types.cpp19
-rw-r--r--test/SemaCXX/nested-name-spec.cpp14
-rw-r--r--test/SemaCXX/no-rtti.cpp10
-rw-r--r--test/SemaCXX/nullptr.cpp4
-rw-r--r--test/SemaCXX/offsetof-0x.cpp20
-rw-r--r--test/SemaCXX/overload-call.cpp34
-rw-r--r--test/SemaCXX/overload-member-call.cpp13
-rw-r--r--test/SemaCXX/overloaded-builtin-operators.cpp33
-rw-r--r--test/SemaCXX/pr13353.cpp13
-rw-r--r--test/SemaCXX/pr13394-crash-on-invalid.cpp16
-rw-r--r--test/SemaCXX/printf-block.cpp18
-rw-r--r--test/SemaCXX/printf-cstr.cpp53
-rw-r--r--test/SemaCXX/qualified-id-lookup.cpp5
-rw-r--r--test/SemaCXX/reinterpret-cast.cpp2
-rw-r--r--test/SemaCXX/static-assert.cpp14
-rw-r--r--test/SemaCXX/switch-implicit-fallthrough-cxx98.cpp119
-rw-r--r--test/SemaCXX/switch-implicit-fallthrough-per-method.cpp51
-rw-r--r--test/SemaCXX/switch-implicit-fallthrough.cpp197
-rw-r--r--test/SemaCXX/type-traits.cpp35
-rw-r--r--test/SemaCXX/typo-correction.cpp44
-rw-r--r--test/SemaCXX/uninit-variables.cpp6
-rw-r--r--test/SemaCXX/uninitialized.cpp165
-rw-r--r--test/SemaCXX/unknown-type-name.cpp56
-rw-r--r--test/SemaCXX/unused.cpp48
-rw-r--r--test/SemaCXX/user-defined-conversions.cpp2
-rw-r--r--test/SemaCXX/virtuals.cpp2
-rw-r--r--test/SemaCXX/warn-deprecated-header.cpp3
-rw-r--r--test/SemaCXX/warn-literal-conversion.cpp28
-rw-r--r--test/SemaCXX/warn-loop-analysis.cpp154
-rw-r--r--test/SemaCXX/warn-memset-bad-sizeof.cpp24
-rw-r--r--test/SemaCXX/warn-static-function-inheader.cpp12
-rw-r--r--test/SemaCXX/warn-static-function-inheader.h3
-rw-r--r--test/SemaCXX/warn-thread-safety-analysis.cpp1008
-rw-r--r--test/SemaCXX/warn-thread-safety-parsing.cpp857
-rw-r--r--test/SemaCXX/warn-unique-enum.cpp27
-rw-r--r--test/SemaCXX/warn-unused-private-field.cpp246
-rw-r--r--test/SemaCXX/warn-unused-value.cpp2
87 files changed, 3882 insertions, 667 deletions
diff --git a/test/SemaCXX/MicrosoftCompatibility.cpp b/test/SemaCXX/MicrosoftCompatibility.cpp
index 3634fa346272..6a48f36801bd 100644
--- a/test/SemaCXX/MicrosoftCompatibility.cpp
+++ b/test/SemaCXX/MicrosoftCompatibility.cpp
@@ -1,6 +1,10 @@
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions
+typedef unsigned short char16_t;
+typedef unsigned int char32_t;
+
+typename decltype(3) a; // expected-warning {{expected a qualified name after 'typename'}}
namespace ms_conversion_rules {
diff --git a/test/SemaCXX/MicrosoftCompatibilityNoExceptions.cpp b/test/SemaCXX/MicrosoftCompatibilityNoExceptions.cpp
new file mode 100644
index 000000000000..d932b5dbbcea
--- /dev/null
+++ b/test/SemaCXX/MicrosoftCompatibilityNoExceptions.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-compatibility
+
+// PR13153
+namespace std {}
+class type_info {};
+void f() {
+ (void)typeid(int);
+}
diff --git a/test/SemaCXX/PR10243.cpp b/test/SemaCXX/PR10243.cpp
index 129ff80e2d2e..19a8b04e84fa 100644
--- a/test/SemaCXX/PR10243.cpp
+++ b/test/SemaCXX/PR10243.cpp
@@ -9,12 +9,12 @@ struct T0 {
struct T1 {
S s; // expected-error{{field has incomplete type 'S'}}
- T1(T1&) = default;
+ T1(const T1&) = default;
};
struct T2 {
S s; // expected-error{{field has incomplete type 'S'}}
- T2& operator=(T2&) = default;
+ T2& operator=(const T2&) = default;
};
struct T3 {
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
index b164d9eda6a5..e20a89009bd9 100644
--- a/test/SemaCXX/abstract.cpp
+++ b/test/SemaCXX/abstract.cpp
@@ -259,3 +259,17 @@ namespace pr9247 {
};
};
}
+
+namespace pr12658 {
+ class C {
+ public:
+ C(int v){}
+ virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
+ };
+
+ void foo( C& c ) {}
+
+ void bar( void ) {
+ foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
+ }
+}
diff --git a/test/SemaCXX/address-of-temporary.cpp b/test/SemaCXX/address-of-temporary.cpp
index eb5dee50598e..bb6cba3187f5 100644
--- a/test/SemaCXX/address-of-temporary.cpp
+++ b/test/SemaCXX/address-of-temporary.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -Wno-error=address-of-temporary -verify %s
-struct X {
+// RUN: %clang_cc1 -fsyntax-only -Wno-error=address-of-temporary -verify -std=gnu++11 %s
+struct X {
X();
X(int);
X(int, int);
@@ -10,3 +10,39 @@ void f1() { (void)&X(1); } // expected-warning{{taking the address of a temporar
void f2() { (void)&X(1, 2); } // expected-warning{{taking the address of a temporary object}}
void f3() { (void)&(X)1; } // expected-warning{{taking the address of a temporary object}}
+
+namespace PointerToArrayDecay {
+ struct Y {
+ int a[4];
+ };
+
+ typedef int A[4];
+
+ template<typename T> void consume(T);
+ struct S { int *p; };
+
+ void g0() { int *p = Y().a; } // expected-warning{{pointer is initialized by a temporary array}}
+ void g1() { int *p = Y{}.a; } // expected-warning{{pointer is initialized by a temporary array}}
+ void g2() { int *p = A{}; } // expected-warning{{pointer is initialized by a temporary array}}
+ void g3() { int *p = (A){}; } // expected-warning{{pointer is initialized by a temporary array}}
+
+ void h0() { consume(Y().a); }
+ void h1() { consume(Y{}.a); }
+ void h2() { consume(A{}); }
+ void h3() { consume((A){}); }
+
+ void i0() { S s = { Y().a }; } // expected-warning{{pointer is initialized by a temporary array}}
+ void i1() { S s = { Y{}.a }; } // expected-warning{{pointer is initialized by a temporary array}}
+ void i2() { S s = { A{} }; } // expected-warning{{pointer is initialized by a temporary array}}
+ void i3() { S s = { (A){} }; } // expected-warning{{pointer is initialized by a temporary array}}
+
+ void j0() { (void)S { Y().a }; }
+ void j1() { (void)S { Y{}.a }; }
+ void j2() { (void)S { A{} }; }
+ void j3() { (void)S { (A){} }; }
+
+ void k0() { consume(S { Y().a }); }
+ void k1() { consume(S { Y{}.a }); }
+ void k2() { consume(S { A{} }); }
+ void k3() { consume(S { (A){} }); }
+}
diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp
index 484dd3379ed7..4bf79f851e0b 100644
--- a/test/SemaCXX/alias-template.cpp
+++ b/test/SemaCXX/alias-template.cpp
@@ -145,3 +145,30 @@ namespace Curried {
template<typename T, typename U> struct S;
template<typename T> template<typename U> using SS = S<T, U>; // expected-error {{extraneous template parameter list in alias template declaration}}
}
+
+// PR12647
+namespace SFINAE {
+ template<bool> struct enable_if; // expected-note 2{{here}}
+ template<> struct enable_if<true> { using type = void; };
+
+ template<typename T> struct is_enum { static constexpr bool value = __is_enum(T); };
+
+ template<typename T> using EnableIf = typename enable_if<T::value>::type; // expected-error {{undefined template}}
+ template<typename T> using DisableIf = typename enable_if<!T::value>::type; // expected-error {{undefined template}}
+
+ template<typename T> EnableIf<is_enum<T>> f();
+ template<typename T> DisableIf<is_enum<T>> f();
+
+ enum E { e };
+
+ int main() {
+ f<int>();
+ f<E>();
+ }
+
+ template<typename T, typename U = EnableIf<is_enum<T>>> struct fail1 {}; // expected-note {{here}}
+ template<typename T> struct fail2 : DisableIf<is_enum<T>> {}; // expected-note {{here}}
+
+ fail1<int> f1; // expected-note {{here}}
+ fail2<E> f2; // expected-note {{here}}
+}
diff --git a/test/SemaCXX/altivec.cpp b/test/SemaCXX/altivec.cpp
index 39421b7c40f4..9de1f04b697c 100644
--- a/test/SemaCXX/altivec.cpp
+++ b/test/SemaCXX/altivec.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -faltivec -fno-lax-vector-conversions -triple powerpc-unknown-unknown -verify %s
+// RUN: %clang_cc1 -faltivec -fno-lax-vector-conversions -triple powerpc-unknown-unknown -fcxx-exceptions -verify %s
typedef int V4i __attribute__((vector_size(16)));
@@ -76,3 +76,8 @@ namespace LValueToRValueConversions {
vector float initFloat = (vector float)(Struct().f); // expected-error {{did you mean to call it}}
vector int initInt = (vector int)(Struct().n); // expected-error {{did you mean to call it}}
}
+
+void f() {
+ try {}
+ catch (vector pixel px) {}
+};
diff --git a/test/SemaCXX/anonymous-union-cxx11.cpp b/test/SemaCXX/anonymous-union-cxx11.cpp
new file mode 100644
index 000000000000..8e682ebcda3d
--- /dev/null
+++ b/test/SemaCXX/anonymous-union-cxx11.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -pedantic %s
+
+namespace PR12866 {
+ struct bar {
+ union {
+ int member;
+ };
+ };
+
+ void foo( void ) {
+ (void)sizeof(bar::member);
+ }
+}
diff --git a/test/SemaCXX/array-bound-merge.cpp b/test/SemaCXX/array-bound-merge.cpp
index 74f58fa12360..8fb2ec52a9ee 100644
--- a/test/SemaCXX/array-bound-merge.cpp
+++ b/test/SemaCXX/array-bound-merge.cpp
@@ -7,3 +7,5 @@ extern int b[10];
int b[];
extern int c[1];
int c[] = {1,2}; // expected-error {{excess elements in array initializer}}
+
+int d[1][]; // expected-error {{array has incomplete element type 'int []'}}
diff --git a/test/SemaCXX/arrow-operator.cpp b/test/SemaCXX/arrow-operator.cpp
index 6535a0a2f201..173ff729fc1b 100644
--- a/test/SemaCXX/arrow-operator.cpp
+++ b/test/SemaCXX/arrow-operator.cpp
@@ -36,3 +36,31 @@ void f()
Line_Segment(node1->Location()); // expected-error {{not a structure or union}}
}
}
+
+
+namespace arrow_suggest {
+
+template <typename T>
+class wrapped_ptr {
+ public:
+ wrapped_ptr(T* ptr) : ptr_(ptr) {}
+ T* operator->() { return ptr_; }
+ void Check(); // expected-note {{'Check' declared here}}
+ private:
+ T *ptr_;
+};
+
+class Worker {
+ public:
+ void DoSomething();
+ void Chuck();
+};
+
+void test() {
+ wrapped_ptr<Worker> worker(new Worker);
+ worker.DoSomething(); // expected-error {{no member named 'DoSomething' in 'arrow_suggest::wrapped_ptr<arrow_suggest::Worker>'; did you mean to use '->' instead of '.'?}}
+ worker.DoSamething(); // expected-error {{no member named 'DoSamething' in 'arrow_suggest::wrapped_ptr<arrow_suggest::Worker>'}}
+ worker.Chuck(); // expected-error {{no member named 'Chuck' in 'arrow_suggest::wrapped_ptr<arrow_suggest::Worker>'; did you mean 'Check'?}}
+}
+
+} // namespace arrow_suggest
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index 46568aabd677..f3d818a75f35 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only
class A {
- void f() __attribute__((deprecated));
+ void f() __attribute__((deprecated)); // expected-note 2 {{declared here}}
void g(A* a);
void h(A* a) __attribute__((deprecated));
- int b __attribute__((deprecated));
+ int b __attribute__((deprecated)); // expected-note 2 {{declared here}}
};
void A::g(A* a)
@@ -26,7 +26,7 @@ void A::h(A* a)
}
struct B {
- virtual void f() __attribute__((deprecated));
+ virtual void f() __attribute__((deprecated)); // expected-note 4 {{declared here}}
void g();
};
@@ -68,20 +68,20 @@ void f(D* d) {
// Overloaded namespace members.
namespace test1 {
- void foo(int) __attribute__((deprecated));
+ void foo(int) __attribute__((deprecated)); // expected-note {{declared here}}
void test1() { foo(10); } // expected-warning {{deprecated}}
- void foo(short) __attribute__((deprecated));
+ void foo(short) __attribute__((deprecated)); // expected-note {{declared here}}
void test2(short s) { foo(s); } // expected-warning {{deprecated}}
void foo(long);
void test3(long l) { foo(l); }
struct A {
- friend void foo(A*) __attribute__((deprecated));
+ friend void foo(A*) __attribute__((deprecated)); // expected-note {{declared here}}
};
void test4(A *a) { foo(a); } // expected-warning {{deprecated}}
namespace ns {
struct Foo {};
- void foo(const Foo &f) __attribute__((deprecated));
+ void foo(const Foo &f) __attribute__((deprecated)); // expected-note {{declared here}}
}
void test5() {
foo(ns::Foo()); // expected-warning {{deprecated}}
@@ -91,9 +91,9 @@ namespace test1 {
// Overloaded class members.
namespace test2 {
struct A {
- void foo(int) __attribute__((deprecated));
+ void foo(int) __attribute__((deprecated)); // expected-note 2 {{declared here}}
void foo(long);
- static void bar(int) __attribute__((deprecated));
+ static void bar(int) __attribute__((deprecated)); // expected-note 3 {{declared here}}
static void bar(long);
void test2(int i, long l);
@@ -120,12 +120,12 @@ namespace test2 {
namespace test3 {
struct A {
void operator*(const A &);
- void operator*(int) __attribute__((deprecated));
+ void operator*(int) __attribute__((deprecated)); // expected-note {{declared here}}
void operator-(const A &) const;
};
void operator+(const A &, const A &);
- void operator+(const A &, int) __attribute__((deprecated));
- void operator-(const A &, int) __attribute__((deprecated));
+ void operator+(const A &, int) __attribute__((deprecated)); // expected-note {{declared here}}
+ void operator-(const A &, int) __attribute__((deprecated)); // expected-note {{declared here}}
void test() {
A a, b;
@@ -143,9 +143,9 @@ namespace test4 {
struct A {
typedef void (*intfn)(int);
typedef void (*unintfn)(unsigned);
- operator intfn() __attribute__((deprecated));
+ operator intfn() __attribute__((deprecated)); // expected-note {{declared here}}
operator unintfn();
- void operator ()(A &) __attribute__((deprecated));
+ void operator ()(A &) __attribute__((deprecated)); // expected-note {{declared here}}
void operator ()(const A &);
};
@@ -163,7 +163,7 @@ namespace test4 {
namespace test5 {
struct A {
- operator int() __attribute__((deprecated));
+ operator int() __attribute__((deprecated)); // expected-note 3 {{declared here}}
operator long();
};
void test1(A a) {
@@ -193,8 +193,8 @@ namespace test5 {
// rdar://problem/8518751
namespace test6 {
- enum __attribute__((deprecated)) A {
- a0
+ enum __attribute__((deprecated)) A { // expected-note {{declared here}}
+ a0 // expected-note {{declared here}}
};
void testA() {
A x; // expected-warning {{'A' is deprecated}}
@@ -202,7 +202,7 @@ namespace test6 {
}
enum B {
- b0 __attribute__((deprecated)),
+ b0 __attribute__((deprecated)), // expected-note {{declared here}}
b1
};
void testB() {
@@ -212,8 +212,8 @@ namespace test6 {
}
template <class T> struct C {
- enum __attribute__((deprecated)) Enum {
- c0
+ enum __attribute__((deprecated)) Enum { // expected-note {{declared here}}
+ c0 // expected-note {{declared here}}
};
};
void testC() {
@@ -224,7 +224,7 @@ namespace test6 {
template <class T> struct D {
enum Enum {
d0,
- d1 __attribute__((deprecated)),
+ d1 __attribute__((deprecated)), // expected-note {{declared here}}
};
};
void testD() {
diff --git a/test/SemaCXX/attr-visibility.cpp b/test/SemaCXX/attr-visibility.cpp
new file mode 100644
index 000000000000..05aa5a33c72e
--- /dev/null
+++ b/test/SemaCXX/attr-visibility.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class Element>
+void foo() {
+}
+template <>
+ __attribute__((visibility("hidden"))) // expected-note {{previous attribute is here}}
+void foo<int>();
+
+template <>
+void foo<int>();
+
+template <>
+ __attribute__((visibility("default"))) // expected-error {{visibility does not match previous declaration}}
+void foo<int>() {
+}
+
+struct x3 {
+ static int y;
+} __attribute((visibility("default"))); // expected-warning {{attribute 'visibility' after definition is ignored}}
diff --git a/test/SemaCXX/bool.cpp b/test/SemaCXX/bool.cpp
index 2b3ab68848eb..f027186735b3 100644
--- a/test/SemaCXX/bool.cpp
+++ b/test/SemaCXX/bool.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-constant-conversion %s
// Bool literals can be enum values.
enum {
diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp
index 993f8e1d7761..ec5eb17b08f3 100644
--- a/test/SemaCXX/condition.cpp
+++ b/test/SemaCXX/condition.cpp
@@ -7,7 +7,7 @@ void test() {
typedef int arr[10];
while (arr x=0) ; // expected-error {{an array type is not allowed here}} expected-error {{array initializer must be an initializer list}}
- while (int f()=0) ; // expected-warning {{interpreted as a function declaration}} expected-note {{initializer}} expected-error {{a function type is not allowed here}}
+ while (int f()=0) ; // expected-error {{a function type is not allowed here}}
struct S {} s;
if (s) ++x; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index 4aee913277e5..a80eda416f4e 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -2,7 +2,7 @@
// C++ rules for ?: are a lot stricter than C rules, and have to take into
// account more conversion options.
-// This test runs in C++0x mode for the contextual conversion of the condition.
+// This test runs in C++11 mode for the contextual conversion of the condition.
struct ToBool { explicit operator bool(); };
@@ -328,3 +328,27 @@ namespace PR9236 {
(void)(true ? (void*)0 : A()); // expected-error{{incompatible operand types}}
}
}
+
+namespace DR587 {
+ template<typename T>
+ const T *f(bool b) {
+ static T t1 = T();
+ static const T t2 = T();
+ return &(b ? t1 : t2);
+ }
+ struct S {};
+ template const int *f(bool);
+ template const S *f(bool);
+
+ extern bool b;
+ int i = 0;
+ const int ci = 0;
+ volatile int vi = 0;
+ const volatile int cvi = 0;
+
+ const int &cir = b ? i : ci;
+ volatile int &vir = b ? vi : i;
+ const volatile int &cvir1 = b ? ci : cvi;
+ const volatile int &cvir2 = b ? cvi : vi;
+ const volatile int &cvir3 = b ? ci : vi; // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}}
+}
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 9f80e7169bb1..a3ead79a8456 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -fsyntax-only -verify -std=c++11 -pedantic %s -Wno-comment
+// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment
namespace StaticAssertFoldTest {
@@ -494,6 +494,27 @@ struct ArrayRVal {
};
static_assert(ArrayRVal().elems[3].f() == 0, "");
+constexpr int selfref[2][2][2] = {
+ selfref[1][1][1] + 1, selfref[0][0][0] + 1,
+ selfref[1][0][1] + 1, selfref[0][1][0] + 1,
+ selfref[1][0][0] + 1, selfref[0][1][1] + 1 };
+static_assert(selfref[0][0][0] == 1, "");
+static_assert(selfref[0][0][1] == 2, "");
+static_assert(selfref[0][1][0] == 1, "");
+static_assert(selfref[0][1][1] == 2, "");
+static_assert(selfref[1][0][0] == 1, "");
+static_assert(selfref[1][0][1] == 3, "");
+static_assert(selfref[1][1][0] == 0, "");
+static_assert(selfref[1][1][1] == 0, "");
+
+struct TrivialDefCtor { int n; };
+typedef TrivialDefCtor TDCArray[2][2];
+static_assert(TDCArray{}[1][1].n == 0, "");
+
+struct NonAggregateTDC : TrivialDefCtor {};
+typedef NonAggregateTDC NATDCArray[2][2];
+static_assert(NATDCArray{}[1][1].n == 0, "");
+
}
namespace DependentValues {
@@ -689,10 +710,16 @@ static_assert(&ok2 == pok2, "");
static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, "");
static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");
-constexpr Base *nullB = 42 - 6 * 7;
+constexpr Base *nullB = 42 - 6 * 7; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *const'}}
static_assert((Bottom*)nullB == 0, "");
static_assert((Derived*)nullB == 0, "");
static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, "");
+Base * nullB2 = '\0'; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *'}}
+Base * nullB3 = (0);
+// We suppress the warning in unevaluated contexts to workaround some gtest
+// behavior. Once this becomes an error this isn't a problem anymore.
+static_assert(nullB == (1 - 1), "");
+
namespace ConversionOperators {
@@ -1213,6 +1240,17 @@ namespace RecursiveOpaqueExpr {
constexpr int arr2[] = { 1, 0, 0, 3, 0, 2, 0, 4, 0, 5 };
static_assert(LastNonzero(begin(arr2), end(arr2)) == 5, "");
+
+ constexpr int arr3[] = {
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ static_assert(LastNonzero(begin(arr3), end(arr3)) == 2, "");
}
namespace VLASizeof {
@@ -1248,3 +1286,91 @@ namespace Vector {
}
constexpr auto v2 = g(4);
}
+
+// PR12626, redux
+namespace InvalidClasses {
+ void test0() {
+ struct X; // expected-note {{forward declaration}}
+ struct Y { bool b; X x; }; // expected-error {{field has incomplete type}}
+ Y y;
+ auto& b = y.b;
+ }
+}
+
+// Constructors can be implicitly constexpr, even for a non-literal type.
+namespace ImplicitConstexpr {
+ struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}}
+ struct R { constexpr R() noexcept; constexpr R(const R&) noexcept; constexpr R(R&&) noexcept; ~R() noexcept; };
+ struct S { R r; }; // expected-note 3{{here}}
+ struct T { T(const T&) noexcept; T(T &&) noexcept; ~T() noexcept; };
+ struct U { T t; }; // expected-note 3{{here}}
+ static_assert(!__is_literal_type(Q), "");
+ static_assert(!__is_literal_type(R), "");
+ static_assert(!__is_literal_type(S), "");
+ static_assert(!__is_literal_type(T), "");
+ static_assert(!__is_literal_type(U), "");
+ struct Test {
+ friend Q::Q() noexcept; // expected-error {{follows constexpr}}
+ friend Q::Q(Q&&) noexcept; // expected-error {{follows constexpr}}
+ friend Q::Q(const Q&) noexcept; // expected-error {{follows constexpr}}
+ friend S::S() noexcept; // expected-error {{follows constexpr}}
+ friend S::S(S&&) noexcept; // expected-error {{follows constexpr}}
+ friend S::S(const S&) noexcept; // expected-error {{follows constexpr}}
+ friend constexpr U::U() noexcept; // expected-error {{follows non-constexpr}}
+ friend constexpr U::U(U&&) noexcept; // expected-error {{follows non-constexpr}}
+ friend constexpr U::U(const U&) noexcept; // expected-error {{follows non-constexpr}}
+ };
+}
+
+// Indirectly test that an implicit lvalue to xvalue conversion performed for
+// an NRVO move operation isn't implemented as CK_LValueToRValue.
+namespace PR12826 {
+ struct Foo {};
+ constexpr Foo id(Foo x) { return x; }
+ constexpr Foo res(id(Foo()));
+}
+
+namespace PR13273 {
+ struct U {
+ int t;
+ U() = default;
+ };
+
+ struct S : U {
+ S() = default;
+ };
+
+ // S's default constructor isn't constexpr, because U's default constructor
+ // doesn't initialize 't', but it's trivial, so value-initialization doesn't
+ // actually call it.
+ static_assert(S{}.t == 0, "");
+}
+
+namespace PR12670 {
+ struct S {
+ constexpr S(int a0) : m(a0) {}
+ constexpr S() : m(6) {}
+ int m;
+ };
+ constexpr S x[3] = { {4}, 5 };
+ static_assert(x[0].m == 4, "");
+ static_assert(x[1].m == 5, "");
+ static_assert(x[2].m == 6, "");
+}
+
+// Indirectly test that an implicit lvalue-to-rvalue conversion is performed
+// when a conditional operator has one argument of type void and where the other
+// is a glvalue of class type.
+namespace ConditionalLValToRVal {
+ struct A {
+ constexpr A(int a) : v(a) {}
+ int v;
+ };
+
+ constexpr A f(const A &a) {
+ return a.v == 0 ? throw a : a;
+ }
+
+ constexpr A a(4);
+ static_assert(f(a).v == 4, "");
+}
diff --git a/test/SemaCXX/constant-expression.cpp b/test/SemaCXX/constant-expression.cpp
index 23a4dda70838..ec50cb7d92fc 100644
--- a/test/SemaCXX/constant-expression.cpp
+++ b/test/SemaCXX/constant-expression.cpp
@@ -115,5 +115,12 @@ int array2[recurse2]; // expected-warning {{variable length array}} expected-war
namespace FloatConvert {
typedef int a[(int)42.3];
typedef int a[(int)42.997];
- typedef int b[(int)4e10]; // expected-warning {{variable length}} expected-error {{variable length}}
+ typedef int b[(long long)4e20]; // expected-warning {{variable length}} expected-error {{variable length}} expected-warning {{'long long' is an extension}}
+}
+
+// PR12626
+namespace test3 {
+ struct X; // expected-note {{forward declaration of 'test3::X'}}
+ struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'test3::X'}}
+ int f() { return Y().b; }
}
diff --git a/test/SemaCXX/constexpr-many-arguments.cpp b/test/SemaCXX/constexpr-many-arguments.cpp
new file mode 100644
index 000000000000..3b5e974b3328
--- /dev/null
+++ b/test/SemaCXX/constexpr-many-arguments.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s
+// PR13197
+
+struct type1
+{
+ constexpr type1(int a0) : my_data{a0} {}
+ int my_data[1];
+};
+
+struct type2
+{
+ typedef type1 T;
+ constexpr type2(T a00, T a01, T a02, T a03, T a04, T a05, T a06, T a07, T a08, T a09,
+ T a10, T a11, T a12, T a13, T a14, T a15, T a16, T a17, T a18, T a19,
+ T a20, T a21, T a22)
+ : my_data{a00, a01, a02, a03, a04, a05, a06, a07, a08, a09,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19,
+ a20, a21, a22}
+ {}
+ type1 my_data[23];
+};
+
+struct type3
+{
+ constexpr type3(type2 a0, type2 a1) : my_data{a0, a1} {}
+ type2 my_data[2];
+};
+
+constexpr type3 g
+{
+ {
+ {0},{0},{0},{0},{0},{0},{0},{0},{0},{0},
+ {0},{0},{0},{0},{0},{0},{0},{0},{0},{0},
+ {0},{0},{0}
+ },
+ {
+ {0},{0},{0},{0},{0},{0},{0},{0},{0},{0},
+ {0},{0},{0},{0},{0},{0},{0},{0},{0},{0},
+ {0},{0},{0}
+ }
+};
+
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index e8b7f0b6760b..f503d01f360d 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -126,21 +126,24 @@ struct Q {
// A silly class used to demonstrate field-is-uninitialized in constructors with
// multiple params.
+int IntParam(int i) { return 0; };
class TwoInOne { public: TwoInOne(TwoInOne a, TwoInOne b) {} };
class InitializeUsingSelfTest {
bool A;
char* B;
int C;
TwoInOne D;
- InitializeUsingSelfTest(int E)
+ int E;
+ InitializeUsingSelfTest(int F)
: A(A), // expected-warning {{field is uninitialized when used here}}
B((((B)))), // expected-warning {{field is uninitialized when used here}}
C(A && InitializeUsingSelfTest::C), // expected-warning {{field is uninitialized when used here}}
D(D, // expected-warning {{field is uninitialized when used here}}
- D) {} // expected-warning {{field is uninitialized when used here}}
+ D), // expected-warning {{field is uninitialized when used here}}
+ E(IntParam(E)) {} // expected-warning {{field is uninitialized when used here}}
};
-int IntWrapper(int i) { return 0; };
+int IntWrapper(int &i) { return 0; };
class InitializeUsingSelfExceptions {
int A;
int B;
@@ -229,13 +232,13 @@ namespace PR7402 {
// <rdar://problem/8308215>: don't crash.
// Lots of questionable recovery here; errors can change.
namespace test3 {
- class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 3 {{candidate}} expected-note {{passing argument}}
+ class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 2 {{candidate}}
class B : public A {
public:
B(const String& s, int e=0) // expected-error {{unknown type name}}
: A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}}
B(const B& e)
- : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{no viable conversion}} expected-error {{does not name}}
+ : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} expected-error {{no member named 'm_String' in 'test3::B'}}
}
};
}
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
index a7a178244c80..6fca0503ba72 100644
--- a/test/SemaCXX/conversion-function.cpp
+++ b/test/SemaCXX/conversion-function.cpp
@@ -392,3 +392,14 @@ namespace PR8800 {
A& a4 = (A&)c;
}
}
+
+namespace PR12712 {
+ struct A {};
+ struct B {
+ operator A();
+ operator A() const;
+ };
+ struct C : B {};
+
+ A f(const C c) { return c; }
+}
diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp
index a64b18721a5f..ac235cc7feaf 100644
--- a/test/SemaCXX/conversion.cpp
+++ b/test/SemaCXX/conversion.cpp
@@ -65,19 +65,69 @@ void test3() {
int c = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}}
int d;
d = ((((NULL)))); // expected-warning {{implicit conversion of NULL constant to 'int'}}
- bool bl = NULL; // FIXME: this should warn but we currently suppress a bunch of conversion-to-bool warnings including this one
+ bool bl = NULL; // expected-warning {{implicit conversion of NULL constant to 'bool'}}
char ch = NULL; // expected-warning {{implicit conversion of NULL constant to 'char'}}
unsigned char uch = NULL; // expected-warning {{implicit conversion of NULL constant to 'unsigned char'}}
short sh = NULL; // expected-warning {{implicit conversion of NULL constant to 'short'}}
+ double dbl = NULL; // expected-warning {{implicit conversion of NULL constant to 'double'}}
// Use FileCheck to ensure we don't get any unnecessary macro-expansion notes
// (that don't appear as 'real' notes & can't be seen/tested by -verify)
// CHECK-NOT: note:
- // CHECK: note: expanded from macro 'FNULL'
-#define FNULL NULL
- int a2 = FNULL; // expected-warning {{implicit conversion of NULL constant to 'int'}}
- // CHECK-NOT: note:
// CHECK: note: expanded from macro 'FINIT'
#define FINIT int a3 = NULL;
FINIT // expected-warning {{implicit conversion of NULL constant to 'int'}}
+
+ // we don't catch the case of #define FOO NULL ... int i = FOO; but that seems a bit narrow anyway
+ // and avoiding that helps us skip these cases:
+#define NULL_COND(cond) ((cond) ? &a : NULL)
+ bool bl2 = NULL_COND(true); // don't warn on NULL conversion through the conditional operator across a macro boundary
+ if (NULL_COND(true))
+ ;
+ while (NULL_COND(true))
+ ;
+ for (; NULL_COND(true); )
+ ;
+ do ;
+ while(NULL_COND(true));
+ int *ip = NULL;
+ int (*fp)() = NULL;
+ struct foo {
+ int n;
+ void func();
+ };
+ int foo::*datamem = NULL;
+ int (foo::*funmem)() = NULL;
+}
+
+namespace test4 {
+ // FIXME: We should warn for non-dependent args (only when the param type is also non-dependent) only once
+ // not once for the template + once for every instantiation
+ template<typename T>
+ void tmpl(char c = NULL, // expected-warning 4 {{implicit conversion of NULL constant to 'char'}}
+ T a = NULL, // expected-warning {{implicit conversion of NULL constant to 'char'}} \
+ expected-warning 2 {{implicit conversion of NULL constant to 'int'}}
+ T b = 1024) { // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1024 to 0}}
+ }
+
+ template<typename T>
+ void tmpl2(T t = NULL) {
+ }
+
+ void func() {
+ tmpl<char>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<char>' required here}}
+ tmpl<int>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<int>' required here}}
+ // FIXME: We should warn only once for each template instantiation - not once for each call
+ tmpl<int>(); // expected-note 2 {{in instantiation of default function argument expression for 'tmpl<int>' required here}}
+ tmpl2<int*>();
+ }
+}
+
+namespace test5 {
+ template<int I>
+ void func() {
+ bool b = I;
+ }
+
+ template void func<3>();
}
diff --git a/test/SemaCXX/crashes.cpp b/test/SemaCXX/crashes.cpp
index b77248ef4104..d02704c87c74 100644
--- a/test/SemaCXX/crashes.cpp
+++ b/test/SemaCXX/crashes.cpp
@@ -104,3 +104,35 @@ namespace PR10270 {
return;
}
}
+
+namespace rdar11806334 {
+
+class cc_YCbCr;
+
+class cc_rgb
+{
+ public:
+ cc_rgb( uint p ); // expected-error {{unknown type name}}
+ cc_rgb( cc_YCbCr v_in );
+};
+
+class cc_hsl
+{
+ public:
+ cc_rgb rgb();
+ cc_YCbCr YCbCr();
+};
+
+class cc_YCbCr
+{
+ public:
+ cc_YCbCr( const cc_rgb v_in );
+};
+
+cc_YCbCr cc_hsl::YCbCr()
+{
+ cc_YCbCr v_out = cc_YCbCr( rgb());
+ return v_out;
+}
+
+}
diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
index 32905956169b..641760e7e540 100644
--- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp
+++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
@@ -7,11 +7,14 @@ struct non_copiable {
};
struct non_const_copy {
- non_const_copy(non_const_copy&) = default; // expected-note {{not viable}}
- non_const_copy& operator = (non_const_copy&) & = default; // expected-note {{not viable}}
- non_const_copy& operator = (non_const_copy&) && = default; // expected-note {{not viable}}
+ non_const_copy(non_const_copy&);
+ non_const_copy& operator = (non_const_copy&) &;
+ non_const_copy& operator = (non_const_copy&) &&;
non_const_copy() = default; // expected-note {{not viable}}
};
+non_const_copy::non_const_copy(non_const_copy&) = default; // expected-note {{not viable}}
+non_const_copy& non_const_copy::operator = (non_const_copy&) & = default; // expected-note {{not viable}}
+non_const_copy& non_const_copy::operator = (non_const_copy&) && = default; // expected-note {{not viable}}
void fn1 () {
non_copiable nc;
@@ -21,7 +24,8 @@ void fn1 () {
non_const_copy ncc;
non_const_copy ncc2 = ncc;
ncc = ncc2;
- const non_const_copy cncc;
+ const non_const_copy cncc{};
+ const non_const_copy cncc1; // expected-error {{default initialization of an object of const type 'const non_const_copy' requires a user-provided default constructor}}
non_const_copy ncc3 = cncc; // expected-error {{no matching}}
ncc = cncc; // expected-error {{no viable overloaded}}
};
@@ -32,9 +36,9 @@ struct non_const_derived : non_const_copy {
};
struct bad_decls {
- bad_decls(volatile bad_decls&) = default; // expected-error {{may not be volatile}}
- bad_decls&& operator = (bad_decls) = default; // expected-error 2{{lvalue reference}}
- bad_decls& operator = (volatile bad_decls&) = default; // expected-error {{may not be volatile}}
+ bad_decls(volatile bad_decls&) = default; // expected-error {{may not be volatile}} expected-error {{must be defaulted outside the class}}
+ bad_decls&& operator = (bad_decls) = default; // expected-error {{lvalue reference}} expected-error {{must return 'bad_decls &'}}
+ bad_decls& operator = (volatile bad_decls&) = default; // expected-error {{may not be volatile}} expected-error {{must be defaulted outside the class}}
bad_decls& operator = (const bad_decls&) const = default; // expected-error {{may not have 'const', 'constexpr' or 'volatile' qualifiers}}
};
@@ -66,10 +70,9 @@ struct except_spec_d_mismatch : except_spec_a, except_spec_b {
};
struct except_spec_d_match : except_spec_a, except_spec_b {
except_spec_d_match() throw(A, B) = default;
-};
+};
// gcc-compatibility: allow attributes on default definitions
// (but not normal definitions)
struct S { S(); };
S::S() __attribute((pure)) = default;
-
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 2e4107c13e2d..ce7ee672ea19 100644
--- a/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -6,26 +6,26 @@ struct foo {
foo() = default;
foo(const foo&) = default;
- foo(foo&) = default;
+ foo(foo&&) = default;
foo& operator = (const foo&) = default;
- foo& operator = (foo&) = default;
+ foo& operator = (foo&&) = default;
~foo() = default;
};
struct bar {
bar();
bar(const bar&);
- bar(bar&);
+ bar(bar&&);
bar& operator = (const bar&);
- bar& operator = (bar&);
+ bar& operator = (bar&&);
~bar();
};
bar::bar() = default;
bar::bar(const bar&) = default;
-bar::bar(bar&) = default;
+bar::bar(bar&&) = default;
bar& bar::operator = (const bar&) = default;
-bar& bar::operator = (bar&) = default;
+bar& bar::operator = (bar&&) = default;
bar::~bar() = default;
static_assert(__is_trivial(foo), "foo should be trivial");
@@ -51,3 +51,101 @@ template<typename T> struct S : T {
struct lit { constexpr lit() {} };
S<lit> s_lit; // ok
S<bar> s_bar; // ok
+
+struct Friends {
+ friend S<bar>::S();
+ friend S<bar>::S(const S&);
+ friend S<bar>::S(S&&);
+};
+
+namespace DefaultedFnExceptionSpec {
+ // DR1330: The exception-specification of an implicitly-declared special
+ // member function is evaluated as needed.
+ template<typename T> T &&declval();
+ template<typename T> struct pair {
+ pair(const pair&) noexcept(noexcept(T(declval<T>())));
+ };
+
+ struct Y;
+ struct X { X(); X(const Y&); };
+ struct Y { pair<X> p; };
+
+ template<typename T>
+ struct A {
+ pair<T> p;
+ };
+ struct B {
+ B();
+ B(const A<B>&);
+ };
+
+ // Don't crash here.
+ void f() {
+ X x = X();
+ (void)noexcept(B(declval<B>()));
+ }
+
+ template<typename T>
+ struct Error {
+ // FIXME: Type canonicalization causes all the errors to point at the first
+ // declaration which has the type 'void () noexcept (T::error)'. We should
+ // get one error for 'Error<int>::Error()' and one for 'Error<int>::~Error()'.
+ void f() noexcept(T::error); // expected-error 2{{has no members}}
+
+ Error() noexcept(T::error);
+ Error(const Error&) noexcept(T::error);
+ Error(Error&&) noexcept(T::error);
+ Error &operator=(const Error&) noexcept(T::error);
+ Error &operator=(Error&&) noexcept(T::error);
+ ~Error() noexcept(T::error);
+ };
+
+ struct DelayImplicit {
+ Error<int> e;
+ };
+
+ // Don't instantiate the exception specification here.
+ void test1(decltype(declval<DelayImplicit>() = DelayImplicit(DelayImplicit())));
+ void test2(decltype(declval<DelayImplicit>() = declval<const DelayImplicit>()));
+ void test3(decltype(DelayImplicit(declval<const DelayImplicit>())));
+
+ // Any odr-use causes the exception specification to be evaluated.
+ struct OdrUse { // \
+ expected-note {{instantiation of exception specification for 'Error'}} \
+ expected-note {{instantiation of exception specification for '~Error'}}
+ Error<int> e;
+ };
+ OdrUse use; // expected-note {{implicit default constructor for 'DefaultedFnExceptionSpec::OdrUse' first required here}}
+}
+
+namespace PR13527 {
+ struct X {
+ X() = delete; // expected-note {{here}}
+ X(const X&) = delete; // expected-note {{here}}
+ X(X&&) = delete; // expected-note {{here}}
+ X &operator=(const X&) = delete; // expected-note {{here}}
+ X &operator=(X&&) = delete; // expected-note {{here}}
+ ~X() = delete; // expected-note {{here}}
+ };
+ X::X() = default; // expected-error {{redefinition}}
+ X::X(const X&) = default; // expected-error {{redefinition}}
+ X::X(X&&) = default; // expected-error {{redefinition}}
+ X &X::operator=(const X&) = default; // expected-error {{redefinition}}
+ X &X::operator=(X&&) = default; // expected-error {{redefinition}}
+ X::~X() = default; // expected-error {{redefinition}}
+
+ struct Y {
+ Y() = default;
+ Y(const Y&) = default;
+ Y(Y&&) = default;
+ Y &operator=(const Y&) = default;
+ Y &operator=(Y&&) = default;
+ ~Y() = default;
+ };
+ Y::Y() = default; // expected-error {{definition of explicitly defaulted}}
+ Y::Y(const Y&) = default; // expected-error {{definition of explicitly defaulted}}
+ Y::Y(Y&&) = default; // expected-error {{definition of explicitly defaulted}}
+ Y &Y::operator=(const Y&) = default; // expected-error {{definition of explicitly defaulted}}
+ Y &Y::operator=(Y&&) = default; // expected-error {{definition of explicitly defaulted}}
+ Y::~Y() = default; // expected-error {{definition of explicitly defaulted}}
+}
diff --git a/test/SemaCXX/cxx0x-initializer-aggregates.cpp b/test/SemaCXX/cxx0x-initializer-aggregates.cpp
index 801a82f57065..c83058a5e196 100644
--- a/test/SemaCXX/cxx0x-initializer-aggregates.cpp
+++ b/test/SemaCXX/cxx0x-initializer-aggregates.cpp
@@ -87,3 +87,32 @@ namespace array_explicit_conversion {
(void)test4{{{1}}}; // expected-note {{in instantiation of template class 'array_explicit_conversion::A<-1>' requested here}}
}
}
+
+namespace sub_constructor {
+ struct DefaultConstructor { // expected-note 2 {{not viable}}
+ DefaultConstructor(); // expected-note {{not viable}}
+ int x;
+ };
+ struct NoDefaultConstructor1 { // expected-note 2 {{not viable}}
+ NoDefaultConstructor1(int); // expected-note {{not viable}}
+ int x;
+ };
+ struct NoDefaultConstructor2 { // expected-note 4 {{not viable}}
+ NoDefaultConstructor2(int,int); // expected-note 2 {{not viable}}
+ int x;
+ };
+
+ struct Aggr {
+ DefaultConstructor a;
+ NoDefaultConstructor1 b;
+ NoDefaultConstructor2 c;
+ };
+
+ Aggr ok1 { {}, {0} , {0,0} };
+ Aggr ok2 = { {}, {0} , {0,0} };
+ Aggr too_many { {0} , {0} , {0,0} }; // expected-error {{no matching constructor for initialization}}
+ Aggr too_few { {} , {0} , {0} }; // expected-error {{no matching constructor for initialization}}
+ Aggr invalid { {} , {&ok1} , {0,0} }; // expected-error {{no matching constructor for initialization}}
+ NoDefaultConstructor2 array_ok[] = { {0,0} , {0,1} };
+ NoDefaultConstructor2 array_error[] = { {0,0} , {0} }; // expected-error {{no matching constructor for initialization}}
+} \ No newline at end of file
diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp
index 09aca24b704b..223e140ffc02 100644
--- a/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -279,5 +279,28 @@ namespace PR12498 {
{
c->foo({ nullptr, 1 }); // expected-error{{initialization of incomplete type 'const PR12498::ArrayRef'}}
}
+}
+
+namespace explicit_default {
+ struct A {
+ explicit A(); // expected-note{{here}}
+ };
+ A a {}; // ok
+ // This is copy-list-initialization, and we choose an explicit constructor
+ // (even though we do so via value-initialization), so the initialization is
+ // ill-formed.
+ A b = {}; // expected-error{{chosen constructor is explicit}}
+}
+namespace init_list_default {
+ struct A {
+ A(std::initializer_list<int>);
+ };
+ A a {}; // calls initializer list constructor
+
+ struct B {
+ B();
+ B(std::initializer_list<int>) = delete;
+ };
+ B b {}; // calls default constructor
}
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 7384309f97da..f11e19ae6f2c 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -175,3 +175,15 @@ namespace PR12436 {
X x({}, 17);
}
+
+namespace rdar11948732 {
+ template<typename T> struct X {};
+
+ struct XCtorInit {
+ XCtorInit(std::initializer_list<X<int>>);
+ };
+
+ void f(X<int> &xi) {
+ XCtorInit xc = { xi, xi };
+ }
+}
diff --git a/test/SemaCXX/cxx98-compat-pedantic.cpp b/test/SemaCXX/cxx98-compat-pedantic.cpp
index 00532d5ac073..c07f64e614d2 100644
--- a/test/SemaCXX/cxx98-compat-pedantic.cpp
+++ b/test/SemaCXX/cxx98-compat-pedantic.cpp
@@ -9,7 +9,7 @@
#line 32768 // expected-warning {{#line number greater than 32767 is incompatible with C++98}}
#define VA_MACRO(x, ...) x // expected-warning {{variadic macros are incompatible with C++98}}
-VA_MACRO(,x) // expected-warning {{empty macro argument list is incompatible with C++98}}
+VA_MACRO(,x) // expected-warning {{empty macro arguments are incompatible with C++98}}
; // expected-warning {{extra ';' outside of a function is incompatible with C++98}}
diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp
index 82a9dc8042c4..37341f885619 100644
--- a/test/SemaCXX/cxx98-compat.cpp
+++ b/test/SemaCXX/cxx98-compat.cpp
@@ -1,7 +1,15 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s
-namespace std { struct type_info; }
+namespace std {
+ struct type_info;
+ using size_t = decltype(sizeof(0)); // expected-warning {{decltype}} expected-warning {{alias}}
+ template<typename T> struct initializer_list {
+ initializer_list(T*, size_t);
+ T *p;
+ size_t n;
+ };
+}
template<typename ...T> // expected-warning {{variadic templates are incompatible with C++98}}
class Variadic1 {};
@@ -39,6 +47,14 @@ void Lambda() {
[]{}(); // expected-warning {{lambda expressions are incompatible with C++98}}
}
+struct Ctor {
+ Ctor(int, char);
+ Ctor(double, long);
+};
+struct InitListCtor {
+ InitListCtor(std::initializer_list<bool>);
+};
+
int InitList(int i = {}) { // expected-warning {{generalized initializer lists are incompatible with C++98}} \
// expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}}
(void)new int {}; // expected-warning {{generalized initializer lists are incompatible with C++98}} \
@@ -48,6 +64,14 @@ int InitList(int i = {}) { // expected-warning {{generalized initializer lists a
int x { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}}
S<int> s = {}; // ok, aggregate
s = {}; // expected-warning {{generalized initializer lists are incompatible with C++98}}
+ std::initializer_list<int> xs = { 1, 2, 3 }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}}
+ auto ys = { 1, 2, 3 }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}} \
+ // expected-warning {{'auto' type specifier is incompatible with C++98}}
+ Ctor c1 = { 1, 2 }; // expected-warning {{constructor call from initializer list is incompatible with C++98}}
+ Ctor c2 = { 3.0, 4l }; // expected-warning {{constructor call from initializer list is incompatible with C++98}}
+ InitListCtor ilc = { true, false }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}}
+ const int &r = { 0 }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
+ struct { int a; const int &r; } rr = { 0, {{0}} }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}}
}
struct DelayedDefaultArgumentParseInitList {
@@ -303,3 +327,38 @@ namespace NonTypeTemplateArgs {
S<const int&, k> s1; // expected-warning {{non-type template argument referring to object 'k' with internal linkage is incompatible with C++98}}
S<void(&)(), f> s2; // expected-warning {{non-type template argument referring to function 'f' with internal linkage is incompatible with C++98}}
}
+
+namespace NullPointerTemplateArg {
+ struct A {};
+ template<int*> struct X {};
+ template<int A::*> struct Y {};
+ X<(int*)0> x; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}}
+ Y<(int A::*)0> y; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}}
+}
+
+namespace PR13480 {
+ struct basic_iterator {
+ basic_iterator(const basic_iterator &it) {}
+ basic_iterator(basic_iterator &it) {} // expected-note {{because type 'PR13480::basic_iterator' has a user-declared copy constructor}}
+ };
+
+ union test {
+ basic_iterator it; // expected-warning {{union member 'it' with a non-trivial copy constructor is incompatible with C++98}}
+ };
+}
+
+namespace AssignOpUnion {
+ struct a {
+ void operator=(const a &it) {}
+ void operator=(a &it) {} // expected-note {{because type 'AssignOpUnion::a' has a user-declared copy assignment operator}}
+ };
+
+ struct b {
+ void operator=(const b &it) {} // expected-note {{because type 'AssignOpUnion::b' has a user-declared copy assignment operator}}
+ };
+
+ union test1 {
+ a x; // expected-warning {{union member 'x' with a non-trivial copy assignment operator is incompatible with C++98}}
+ b y; // expected-warning {{union member 'y' with a non-trivial copy assignment operator is incompatible with C++98}}
+ };
+}
diff --git a/test/SemaCXX/dcl_ambig_res.cpp b/test/SemaCXX/dcl_ambig_res.cpp
index fa71b11ba160..08867c0ea2f5 100644
--- a/test/SemaCXX/dcl_ambig_res.cpp
+++ b/test/SemaCXX/dcl_ambig_res.cpp
@@ -10,9 +10,9 @@ int returns_an_int();
void foo(double a)
{
- S w(int(a)); // expected-warning{{disambiguated}}
+ S w(int(a)); // expected-warning{{disambiguated as a function declaration}} expected-note{{add a pair of parentheses}}
w(17);
- S x1(int()); // expected-warning{{disambiguated}}
+ S x1(int()); // expected-warning{{disambiguated as a function declaration}} expected-note{{add a pair of parentheses}}
x1(&returns_an_int);
S y((int)a);
y.bar();
@@ -69,7 +69,7 @@ struct S5 {
static bool const value = false;
};
int foo8() {
- int v(int(S5::value)); // expected-warning{{disambiguated}} expected-error{{parameter declarator cannot be qualified}}
+ int v(int(S5::value)); // expected-warning{{disambiguated as a function declaration}} expected-note{{add a pair of parentheses}} expected-error{{parameter declarator cannot be qualified}}
}
template<typename T>
diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp
index bd3de9eb7e19..8c5e654fca2e 100644
--- a/test/SemaCXX/dcl_init_aggr.cpp
+++ b/test/SemaCXX/dcl_init_aggr.cpp
@@ -15,7 +15,7 @@ struct NonAggregate {
};
NonAggregate non_aggregate_test = { 1, 2 }; // expected-error{{non-aggregate type 'NonAggregate' cannot be initialized with an initializer list}}
-NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error 2 {{initialization of non-aggregate type 'NonAggregate' with an initializer list}}
+NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error 2 {{non-aggregate type 'NonAggregate' cannot be initialized with an initializer list}}
// C++ [dcl.init.aggr]p3
diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp
index 6f4d08cc686c..0980c40cbfd5 100644
--- a/test/SemaCXX/decl-expr-ambiguity.cpp
+++ b/test/SemaCXX/decl-expr-ambiguity.cpp
@@ -22,10 +22,10 @@ void f() {
(int())1; // expected-error {{C-style cast from 'int' to 'int ()' is not allowed}}
// Declarations.
- int fd(T(a)); // expected-warning {{parentheses were disambiguated as a function declarator}}
- T(*d)(int(p)); // expected-warning {{parentheses were disambiguated as a function declarator}} expected-note {{previous definition is here}}
- typedef T(*td)(int(p));
- extern T(*tp)(int(p));
+ int fd(T(a)); // expected-warning {{disambiguated as a function declaration}} expected-note{{add a pair of parentheses}}
+ T(*d)(int(p)); // expected-note {{previous}}
+ typedef T td(int(p));
+ extern T tp(int(p));
T d3(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
T d3v(void);
typedef T d3t();
@@ -49,6 +49,7 @@ struct RAII {
};
void func();
+void func2(short);
namespace N {
struct S;
@@ -59,6 +60,10 @@ namespace N {
S s(); // expected-warning {{function declaration}}
}
+ void nonEmptyParens() {
+ int f = 0, // g = 0; expected-note {{change this ',' to a ';' to call 'func2'}}
+ func2(short(f)); // expected-warning {{function declaration}} expected-note {{add a pair of parentheses}}
+ }
}
class C { };
@@ -70,3 +75,23 @@ void foo() {
fn(1); // expected-error {{no matching function}}
fn(g); // OK
}
+
+namespace PR11874 {
+void foo(); // expected-note 3 {{class 'foo' is hidden by a non-type declaration of 'foo' here}}
+class foo {};
+class bar {
+ bar() {
+ const foo* f1 = 0; // expected-error {{must use 'class' tag to refer to type 'foo' in this scope}}
+ foo* f2 = 0; // expected-error {{must use 'class' tag to refer to type 'foo' in this scope}}
+ foo f3; // expected-error {{must use 'class' tag to refer to type 'foo' in this scope}}
+ }
+};
+
+int baz; // expected-note 2 {{class 'baz' is hidden by a non-type declaration of 'baz' here}}
+class baz {};
+void fizbin() {
+ const baz* b1 = 0; // expected-error {{must use 'class' tag to refer to type 'baz' in this scope}}
+ baz* b2; // expected-error {{use of undeclared identifier 'b2'}}
+ baz b3; // expected-error {{must use 'class' tag to refer to type 'baz' in this scope}}
+}
+}
diff --git a/test/SemaCXX/default1.cpp b/test/SemaCXX/default1.cpp
index ae6ef9791c2a..c8c197e153d4 100644
--- a/test/SemaCXX/default1.cpp
+++ b/test/SemaCXX/default1.cpp
@@ -47,6 +47,13 @@ int i () {
void j (int f = 4);
{
void j (int f); // expected-note{{'j' declared here}}
- j(); // expected-error{{too few arguments to function call, expected 1, have 0}}
+ j(); // expected-error{{too few arguments to function call, single argument 'f' was not specified}}
+ }
+}
+
+int i2() {
+ void j(int f = 4); // expected-note{{'j' declared here}}
+ {
+ j(2, 3); // expected-error{{too many arguments to function call, expected at most single argument 'f', have 2}}
}
}
diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp
index d13fd0eb7b4f..e78e7edc7199 100644
--- a/test/SemaCXX/deleted-function.cpp
+++ b/test/SemaCXX/deleted-function.cpp
@@ -55,3 +55,13 @@ struct Z : virtual DelDtor {
~Z() {} // expected-error {{attempt to use a deleted function}}
};
DelDtor dd; // expected-error {{attempt to use a deleted function}}
+
+template<typename> void test2() = delete;
+template void test2<int>();
+
+template<typename> void test3() = delete;
+template<typename> void test3();
+template void test3<int>();
+
+void test4() {} // expected-note {{previous definition is here}}
+void test4() = delete; // expected-error {{redefinition of 'test4'}}
diff --git a/test/SemaCXX/deleted-operator.cpp b/test/SemaCXX/deleted-operator.cpp
index 0e0282ad12cc..9f53e71d456c 100644
--- a/test/SemaCXX/deleted-operator.cpp
+++ b/test/SemaCXX/deleted-operator.cpp
@@ -8,8 +8,8 @@ struct PR10757 {
int PR10757f() {
PR10757 a1;
// FIXME: We get a ridiculous number of "built-in candidate" notes here...
- if(~a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 6 {{built-in candidate}}
- if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 81 {{built-in candidate}}
+ if(~a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 8 {{built-in candidate}}
+ if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 121 {{built-in candidate}}
}
struct DelOpDel {
diff --git a/test/SemaCXX/elaborated-type-specifier.cpp b/test/SemaCXX/elaborated-type-specifier.cpp
index 760079f3b0bc..1b1770a89f85 100644
--- a/test/SemaCXX/elaborated-type-specifier.cpp
+++ b/test/SemaCXX/elaborated-type-specifier.cpp
@@ -19,7 +19,7 @@ bool test_elab(S1 *s1, struct S2 *s2, struct S3 *s3) {
namespace NS {
class X {
public:
- void test_elab2(struct S4 *s4);
+ void test_elab2(struct S4 *s4); // expected-note{{'NS::S4' declared here}}
};
void X::test_elab2(S4 *s4) { } // expected-note{{passing argument to parameter 's4' here}}
@@ -35,8 +35,7 @@ namespace NS {
}
void test_S5_scope() {
- S4 *s4; // expected-error{{use of undeclared identifier 'S4'}} \
- // expected-error{{use of undeclared identifier 's4'}}
+ S4 *s4; // expected-error{{unknown type name 'S4'; did you mean 'NS::S4'?}}
}
int test_funcparam_scope(struct S5 * s5) {
@@ -44,5 +43,3 @@ int test_funcparam_scope(struct S5 * s5) {
if (s5 == s5_2) return 1; // expected-error {{comparison of distinct pointer types ('struct S5 *' and 'struct S5 *')}}
return 0;
}
-
-
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index ebe924535850..a1f911d79d39 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -245,3 +245,10 @@ namespace test10 {
int m = g<int>();
int n = g<short>(); // expected-note {{here}}
}
+
+namespace pr13128 {
+ // This should compile cleanly
+ class C {
+ enum class E { C };
+ };
+}
diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp
index 355833e693fa..2635fb8d176a 100644
--- a/test/SemaCXX/expressions.cpp
+++ b/test/SemaCXX/expressions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-constant-conversion %s
void choice(int);
int choice(bool);
diff --git a/test/SemaCXX/format-strings-0x.cpp b/test/SemaCXX/format-strings-0x.cpp
index e7c5904c66e3..7b3aef1ee5da 100644
--- a/test/SemaCXX/format-strings-0x.cpp
+++ b/test/SemaCXX/format-strings-0x.cpp
@@ -12,4 +12,16 @@ void f(char **sp, float *fp) {
scanf("%afoobar", fp);
printf(nullptr);
printf(*sp); // expected-warning {{not a string literal}}
+
+ // PR13099
+ printf(
+ R"foobar(%)foobar"
+ R"bazquux(d)bazquux" // expected-warning {{more '%' conversions than data arguments}}
+ R"xyzzy()xyzzy");
+
+ printf(u8"this is %d test", 0); // ok
+ printf(u8R"foo(
+ \u1234\U0010fffe
+ %d)foo" // expected-warning {{more '%' conversions than data arguments}}
+ );
}
diff --git a/test/SemaCXX/function-extern-c.cpp b/test/SemaCXX/function-extern-c.cpp
index f20cd38a3cb0..16dbbb26fc66 100644
--- a/test/SemaCXX/function-extern-c.cpp
+++ b/test/SemaCXX/function-extern-c.cpp
@@ -36,3 +36,5 @@ extern "C" void f7( U u );
extern "C" double f8(void);
extern "C" long long f11( void );
extern "C" A *f10( void );
+
+extern "C" struct mypodstruct f12(); // expected-warning {{'f12' has C-linkage specified, but returns incomplete type 'struct mypodstruct' which could be incompatible with C}}
diff --git a/test/SemaCXX/function-redecl.cpp b/test/SemaCXX/function-redecl.cpp
index 0eb109d2633b..b9d1f23af402 100644
--- a/test/SemaCXX/function-redecl.cpp
+++ b/test/SemaCXX/function-redecl.cpp
@@ -76,12 +76,9 @@ class Crash {
void GetCart(int count) const;
};
// This out-of-line definition was fine...
-void Crash::cart(int count) const {} // expected-error {{out-of-line definition of 'cart' does not match any declaration in 'Crash'}} \
- // expected-note {{'cart' declared here}} \
- // expected-note {{previous definition is here}}
+void Crash::cart(int count) const {} // expected-error {{out-of-line definition of 'cart' does not match any declaration in 'Crash'}}
// ...while this one crashed clang
-void Crash::chart(int count) const {} // expected-error {{out-of-line definition of 'chart' does not match any declaration in 'Crash'; did you mean 'cart'?}} \
- // expected-error {{redefinition of 'cart'}}
+void Crash::chart(int count) const {} // expected-error {{out-of-line definition of 'chart' does not match any declaration in 'Crash'}}
class TestConst {
public:
@@ -98,3 +95,24 @@ void TestConst::setit(int) const { // expected-error {{out-of-line definition of
struct J { int typo() const; };
int J::typo_() { return 3; } // expected-error {{out-of-line definition of 'typo_' does not match any declaration in 'J'}}
+
+// Ensure we correct the redecl of Foo::isGood to Bar::Foo::isGood and not
+// Foo::IsGood even though Foo::IsGood is technically a closer match since it
+// already has a body. Also make sure Foo::beEvil is corrected to Foo::BeEvil
+// since it is a closer match than Bar::Foo::beEvil and neither have a body.
+namespace redecl_typo {
+namespace Foo {
+ bool IsGood() { return false; }
+ void BeEvil(); // expected-note {{'BeEvil' declared here}}
+}
+namespace Bar {
+ namespace Foo {
+ bool isGood(); // expected-note {{'Bar::Foo::isGood' declared here}}
+ void beEvil();
+ }
+}
+bool Foo::isGood() { // expected-error {{out-of-line definition of 'isGood' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'Bar::Foo::isGood'?}}
+ return true;
+}
+void Foo::beEvil() {} // expected-error {{out-of-line definition of 'beEvil' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'BeEvil'?}}
+}
diff --git a/test/SemaCXX/implicit-exception-spec.cpp b/test/SemaCXX/implicit-exception-spec.cpp
index 25316f8d51ee..b29cff5c5d12 100644
--- a/test/SemaCXX/implicit-exception-spec.cpp
+++ b/test/SemaCXX/implicit-exception-spec.cpp
@@ -17,7 +17,7 @@ namespace InClassInitializers {
// is false.
bool ThrowSomething() noexcept(false);
struct ConstExpr {
- bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{exception specification is not available until end of class definition}}
+ bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{cannot be used by non-static data member initializer}}
};
// We can use it now.
bool w = noexcept(ConstExpr());
@@ -25,18 +25,27 @@ namespace InClassInitializers {
// Much more obviously broken: we can't parse the initializer without already
// knowing whether it produces a noexcept expression.
struct TemplateArg {
- int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{exception specification is not available until end of class definition}}
+ int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{cannot be used by non-static data member initializer}}
};
bool x = noexcept(TemplateArg());
// And within a nested class.
+ // FIXME: The diagnostic location is terrible here.
struct Nested {
struct Inner {
- int n = ExceptionIf<noexcept(Nested())>::f(); // expected-error {{exception specification is not available until end of class definition}}
- } inner;
+ int n = ExceptionIf<noexcept(Nested())>::f();
+ } inner; // expected-error {{cannot be used by non-static data member initializer}}
};
bool y = noexcept(Nested());
bool z = noexcept(Nested::Inner());
+
+ struct Nested2 {
+ struct Inner;
+ int n = Inner().n; // expected-error {{cannot be used by non-static data member initializer}}
+ struct Inner {
+ int n = ExceptionIf<noexcept(Nested())>::f();
+ } inner;
+ };
}
namespace ExceptionSpecification {
diff --git a/test/SemaCXX/invalid-member-expr.cpp b/test/SemaCXX/invalid-member-expr.cpp
index 287d9af13094..87da79a27c0c 100644
--- a/test/SemaCXX/invalid-member-expr.cpp
+++ b/test/SemaCXX/invalid-member-expr.cpp
@@ -37,3 +37,34 @@ namespace test3 {
string::iterator i = s.foo(); // expected-error {{no member named 'foo'}}
}
}
+
+
+// Make sure we don't crash.
+namespace rdar11293995 {
+
+struct Length {
+ explicit Length(PassRefPtr<CalculationValue>); // expected-error {{unknown type name}} \
+ expected-error {{expected ')'}} \
+ expected-note {{to match this '('}}
+};
+
+struct LengthSize {
+ Length m_width;
+ Length m_height;
+};
+
+enum EFillSizeType { Contain, Cover, SizeLength, SizeNone };
+
+struct FillSize {
+ EFillSizeType type;
+ LengthSize size;
+};
+
+class FillLayer {
+public:
+ void setSize(FillSize f) { m_sizeType = f.type;}
+private:
+ unsigned m_sizeType : 2;
+};
+
+}
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index e91dee92edb1..0fd634502bc9 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -17,74 +17,71 @@ namespace ExplicitCapture {
[this](){(void)Member;};
[this]{[this]{};};
[]{[this]{};};// expected-error {{'this' cannot be implicitly captured in this context}}
- []{Overload(3);};
- []{Overload();}; // expected-error {{'this' cannot be implicitly captured in this context}}
+ []{Overload(3);};
+ []{Overload();}; // expected-error {{'this' cannot be implicitly captured in this context}}
[]{(void)typeid(Overload());};
- []{(void)typeid(Overload(.5f));};// expected-error {{'this' cannot be implicitly captured in this context}}
+ []{(void)typeid(Overload(.5f));};// expected-error {{'this' cannot be implicitly captured in this context}}
}
};
void f() {
- [this] () {}; // expected-error {{'this' cannot be captured in this context}}
+ [this] () {}; // expected-error {{'this' cannot be captured in this context}}
}
}
namespace ReturnDeduction {
void test() {
- [](){ return 1; };
- [](){ return 1; };
- [](){ return ({return 1; 1;}); };
- [](){ return ({return 'c'; 1;}); }; // expected-error {{must match previous return type}} \
- // expected-warning{{omitted result type}}
- []()->int{ return 'c'; return 1; };
+ [](){ return 1; };
+ [](){ return 1; };
+ [](){ return ({return 1; 1;}); };
+ [](){ return ({return 'c'; 1;}); }; // expected-error {{must match previous return type}}
+ []()->int{ return 'c'; return 1; };
[](){ return 'c'; return 1; }; // expected-error {{must match previous return type}}
- []() { return; return (void)0; };
- [](){ return 1; return 1; }; // expected-warning{{omitted result type}}
+ []() { return; return (void)0; };
+ [](){ return 1; return 1; };
}
}
namespace ImplicitCapture {
void test() {
int a = 0; // expected-note 5 {{declared}}
- []() { return a; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{begins here}}
- [&]() { return a; };
- [=]() { return a; };
- [=]() { int* b = &a; }; // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'}}
+ []() { return a; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{begins here}}
+ [&]() { return a; };
+ [=]() { return a; };
+ [=]() { int* b = &a; }; // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'}}
[=]() { return [&]() { return a; }; };
- []() { return [&]() { return a; }; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
- []() { return ^{ return a; }; };// expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
- []() { return [&a] { return a; }; }; // expected-error 2 {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note 2 {{lambda expression begins here}}
- [=]() { return [&a] { return a; }; }; //
+ []() { return [&]() { return a; }; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
+ []() { return ^{ return a; }; };// expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
+ []() { return [&a] { return a; }; }; // expected-error 2 {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note 2 {{lambda expression begins here}}
+ [=]() { return [&a] { return a; }; }; //
const int b = 2;
- []() { return b; };
+ []() { return b; };
union { // expected-note {{declared}}
int c;
float d;
};
d = 3;
- [=]() { return c; }; // expected-error {{unnamed variable cannot be implicitly captured in a lambda expression}}
+ [=]() { return c; }; // expected-error {{unnamed variable cannot be implicitly captured in a lambda expression}}
__block int e; // expected-note 3 {{declared}}
- [&]() { return e; }; // expected-error {{__block variable 'e' cannot be captured in a lambda expression}}
- [&e]() { return e; }; // expected-error 2 {{__block variable 'e' cannot be captured in a lambda expression}}
+ [&]() { return e; }; // expected-error {{__block variable 'e' cannot be captured in a lambda expression}}
+ [&e]() { return e; }; // expected-error 2 {{__block variable 'e' cannot be captured in a lambda expression}}
int f[10]; // expected-note {{declared}}
- [&]() { return f[2]; };
+ [&]() { return f[2]; };
(void) ^{ return []() { return f[2]; }; }; // expected-error {{variable 'f' cannot be implicitly captured in a lambda with no capture-default specified}} \
// expected-note{{lambda expression begins here}}
struct G { G(); G(G&); int a; }; // expected-note 6 {{not viable}}
G g;
- [=]() { const G* gg = &g; return gg->a; }; // expected-warning{{omitted result type}}
- [=]() { return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error {{no matching constructor for initialization of 'ImplicitCapture::G'}} \
- // expected-warning{{omitted result type}}
- (void)^{ return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error 2 {{no matching constructor for initialization of 'const ImplicitCapture::G'}} \
- // expected-warning{{omitted result type}}
+ [=]() { const G* gg = &g; return gg->a; };
+ [=]() { return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error {{no matching constructor for initialization of 'ImplicitCapture::G'}}
+ (void)^{ return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error 2 {{no matching constructor for initialization of 'const ImplicitCapture::G'}}
const int h = a; // expected-note {{declared}}
- []() { return h; }; // expected-error {{variable 'h' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
+ []() { return h; }; // expected-error {{variable 'h' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
// The exemption for variables which can appear in constant expressions
// applies only to objects (and not to references).
@@ -120,16 +117,16 @@ namespace NullPtr {
const int m = 0;
[=] {
- int &k = f(m); // a null pointer constant
+ int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
} ();
[=] () -> bool {
- int &k = f(m); // a null pointer constant
+ int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
return &m == 0;
} ();
[m] {
- int &k = f(m); // a null pointer constant
+ int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
} ();
}
}
@@ -148,3 +145,79 @@ namespace ModifyingCapture {
};
}
}
+
+namespace VariadicPackExpansion {
+ template<typename T, typename U> using Fst = T;
+ template<typename...Ts> bool g(Fst<bool, Ts> ...bools);
+ template<typename...Ts> bool f(Ts &&...ts) {
+ return g<Ts...>([&ts] {
+ if (!ts)
+ return false;
+ --ts;
+ return true;
+ } () ...);
+ }
+ void h() {
+ int a = 5, b = 2, c = 3;
+ while (f(a, b, c)) {
+ }
+ }
+
+ struct sink {
+ template<typename...Ts> sink(Ts &&...) {}
+ };
+
+ template<typename...Ts> void local_class() {
+ sink {
+ [] (Ts t) {
+ struct S : Ts {
+ void f(Ts t) {
+ Ts &that = *this;
+ that = t;
+ }
+ Ts g() { return *this; };
+ };
+ S s;
+ s.f(t);
+ return s;
+ } (Ts()).g() ...
+ };
+ };
+ struct X {}; struct Y {};
+ template void local_class<X, Y>();
+
+ template<typename...Ts> void nested(Ts ...ts) {
+ f(
+ // Each expansion of this lambda implicitly captures all of 'ts', because
+ // the inner lambda also expands 'ts'.
+ [&] {
+ return ts + [&] { return f(ts...); } ();
+ } () ...
+ );
+ }
+ template void nested(int, int, int);
+
+ template<typename...Ts> void nested2(Ts ...ts) { // expected-note 2{{here}}
+ // Capture all 'ts', use only one.
+ f([&ts...] { return ts; } ()...);
+ // Capture each 'ts', use it.
+ f([&ts] { return ts; } ()...);
+ // Capture all 'ts', use all of them.
+ f([&ts...] { return (int)f(ts...); } ());
+ // Capture each 'ts', use all of them. Ill-formed. In more detail:
+ //
+ // We instantiate two lambdas here; the first captures ts$0, the second
+ // captures ts$1. Both of them reference both ts parameters, so both are
+ // ill-formed because ts can't be implicitly captured.
+ //
+ // FIXME: This diagnostic does not explain what's happening. We should
+ // specify which 'ts' we're referring to in its diagnostic name. We should
+ // also say which slice of the pack expansion is being performed in the
+ // instantiation backtrace.
+ f([&ts] { return (int)f(ts...); } ()...); // \
+ // expected-error 2{{'ts' cannot be implicitly captured}} \
+ // expected-note 2{{lambda expression begins here}}
+ }
+ template void nested2(int); // ok
+ template void nested2(int, int); // expected-note {{in instantiation of}}
+}
diff --git a/test/SemaCXX/literal-operators.cpp b/test/SemaCXX/literal-operators.cpp
index 7f68cd393cad..f4c5c35a2bcb 100644
--- a/test/SemaCXX/literal-operators.cpp
+++ b/test/SemaCXX/literal-operators.cpp
@@ -41,3 +41,4 @@ void operator "" _cv_good (volatile const char *, const size_t); // expected-err
template <char...> void operator "" _good ();
// FIXME: Test some invalid decls that might crop up.
+template <typename...> void operator "" _invalid(); // expected-error {{parameter declaration for literal operator 'operator "" _invalid' is not valid}}
diff --git a/test/SemaCXX/long-virtual-inheritance-chain.cpp b/test/SemaCXX/long-virtual-inheritance-chain.cpp
new file mode 100644
index 000000000000..85995971d240
--- /dev/null
+++ b/test/SemaCXX/long-virtual-inheritance-chain.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+class test0 { virtual void f(); };
+class test1 : virtual test0 { virtual void f(); };
+class test2 : virtual test1 { virtual void f(); };
+class test3 : virtual test2 { virtual void f(); };
+class test4 : virtual test3 { virtual void f(); };
+class test5 : virtual test4 { virtual void f(); };
+class test6 : virtual test5 { virtual void f(); };
+class test7 : virtual test6 { virtual void f(); };
+class test8 : virtual test7 { virtual void f(); };
+class test9 : virtual test8 { virtual void f(); };
+class test10 : virtual test9 { virtual void f(); };
+class test11 : virtual test10 { virtual void f(); };
+class test12 : virtual test11 { virtual void f(); };
+class test13 : virtual test12 { virtual void f(); };
+class test14 : virtual test13 { virtual void f(); };
+class test15 : virtual test14 { virtual void f(); };
+class test16 : virtual test15 { virtual void f(); };
+class test17 : virtual test16 { virtual void f(); };
+class test18 : virtual test17 { virtual void f(); };
+class test19 : virtual test18 { virtual void f(); };
+class test20 : virtual test19 { virtual void f(); };
+class test21 : virtual test20 { virtual void f(); };
+class test22 : virtual test21 { virtual void f(); };
+class test23 : virtual test22 { virtual void f(); };
+class test24 : virtual test23 { virtual void f(); };
+class test25 : virtual test24 { virtual void f(); };
+class test26 : virtual test25 { virtual void f(); };
+class test27 : virtual test26 { virtual void f(); };
+class test28 : virtual test27 { virtual void f(); };
+class test29 : virtual test28 { virtual void f(); };
+class test30 : virtual test29 { virtual void f(); };
+class test31 : virtual test30 { virtual void f(); };
+class test32 : virtual test31 { virtual void f(); };
+class test33 : virtual test32 { virtual void f(); };
+class test34 : virtual test33 { virtual void f(); };
+class test35 : virtual test34 { virtual void f(); };
+class test36 : virtual test35 { virtual void f(); };
+class test37 : virtual test36 { virtual void f(); };
+class test38 : virtual test37 { virtual void f(); };
+class test39 : virtual test38 { virtual void f(); };
+class test40 : virtual test39 { virtual void f(); };
+class test41 : virtual test40 { virtual void f(); };
+class test42 : virtual test41 { virtual void f(); };
+class test43 : virtual test42 { virtual void f(); };
+class test44 : virtual test43 { virtual void f(); };
+class test45 : virtual test44 { virtual void f(); };
+class test46 : virtual test45 { virtual void f(); };
+class test47 : virtual test46 { virtual void f(); };
+class test48 : virtual test47 { virtual void f(); };
+class test49 : virtual test48 { virtual void f(); };
+class test50 : virtual test49 { virtual void f(); };
diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp
index dbddd1c2e3e1..763f9c754c1e 100644
--- a/test/SemaCXX/member-expr.cpp
+++ b/test/SemaCXX/member-expr.cpp
@@ -157,3 +157,13 @@ namespace FuncInMemberExpr {
Vec fun3(int x = 0);
int test3() { return fun3.size(); } // expected-error {{base of member reference is a function; perhaps you meant to call it with no arguments}}
}
+
+namespace DotForSemiTypo {
+void f(int i) {
+ // If the programmer typo'd '.' for ';', make sure we point at the '.' rather
+ // than the "field name" (whatever the first token on the next line happens to
+ // be).
+ int j = i. // expected-error {{member reference base type 'int' is not a structure or union}}
+ j = 0;
+}
+}
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index c93c85bbf89a..a13941fce5d8 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -14,7 +14,7 @@ public:
bool b();
int k;
struct Recurse {
- int &n = b() ? Recurse().n : k; // ok
+ int &n = b() ? Recurse().n : k; // expected-error {{defaulted default constructor of 'Recurse' cannot be used by non-static data member initializer which appears before end of class definition}}
};
struct UnknownBound {
@@ -28,7 +28,7 @@ template<> struct T<2> { template<int C, int D> using B = int; };
const int C = 0, D = 0;
struct S {
int as[] = { decltype(x)::B<C, D>(0) }; // expected-error {{array bound cannot be deduced from an in-class initializer}}
- T<sizeof(as) / sizeof(int)> x; // expected-error {{requires a type specifier}}
+ T<sizeof(as) / sizeof(int)> x;
// test that we handle invalid array bound deductions without crashing when the declarator name is itself invalid
operator int[](){}; // expected-error {{'operator int' cannot be the name of a variable or data member}} \
// expected-error {{array bound cannot be deduced from an in-class initializer}}
diff --git a/test/SemaCXX/member-operator-expr.cpp b/test/SemaCXX/member-operator-expr.cpp
index ae5f8bb0ddb6..c98ef7399709 100644
--- a/test/SemaCXX/member-operator-expr.cpp
+++ b/test/SemaCXX/member-operator-expr.cpp
@@ -27,3 +27,8 @@ void test2() {
x->operator float(); // expected-error{{no member named 'operator float'}}
x->operator; // expected-error{{expected a type}}
}
+
+namespace pr13157 {
+ class A { public: void operator()(int x, int y = 2, ...) {} };
+ void f() { A()(1); }
+} \ No newline at end of file
diff --git a/test/SemaCXX/microsoft-cxx0x.cpp b/test/SemaCXX/microsoft-cxx0x.cpp
index 3b9bbefc0cd6..79bd7c39e5a5 100644
--- a/test/SemaCXX/microsoft-cxx0x.cpp
+++ b/test/SemaCXX/microsoft-cxx0x.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wc++11-narrowing -Wmicrosoft -verify -fms-extensions -std=c++11
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wc++11-narrowing -Wmicrosoft -verify -fms-extensions -std=c++11 -fms-compatibility -DMS_COMPAT
struct A {
@@ -6,3 +7,16 @@ struct A {
};
int b = 3;
A var = { b }; // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+
+
+namespace PR13433 {
+ struct S;
+ S make();
+
+ template<typename F> auto x(F f) -> decltype(f(make()));
+#ifndef MS_COMPAT
+// expected-error@-2{{calling 'make' with incomplete return type 'PR13433::S'}}
+// expected-note@-5{{'make' declared here}}
+// expected-note@-7{{forward declaration of 'PR13433::S'}}
+#endif
+}
diff --git a/test/SemaCXX/neon-vector-types.cpp b/test/SemaCXX/neon-vector-types.cpp
index aa82b11e8cd7..336fcd4f18d6 100644
--- a/test/SemaCXX/neon-vector-types.cpp
+++ b/test/SemaCXX/neon-vector-types.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify "-triple" "thumbv7-apple-ios3.0.0" %s
// rdar://9208404
typedef int MP4Err;
@@ -25,3 +25,20 @@ MP4Err autoCorrelation2nd_Neon(Float32 *alphar, Float32 *alphai,
return 0;
}
+namespace rdar11688587 {
+ typedef float float32_t;
+ typedef __attribute__((neon_vector_type(4))) float32_t float32x4_t;
+
+ template<int I>
+ float test()
+ {
+ extern float32x4_t vec;
+ return __extension__ ({
+ float32x4_t __a = (vec);
+ (float32_t)__builtin_neon_vgetq_lane_f32(__a, I); // expected-error{{argument should be a value from 0 to 3}}
+ });
+ }
+
+ template float test<1>();
+ template float test<4>(); // expected-note{{in instantiation of function template specialization 'rdar11688587::test<4>' requested here}}
+}
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index b31763484489..4e1abc5e5bc8 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -143,7 +143,7 @@ namespace A {
void g(int&); // expected-note{{type of 1st parameter of member declaration does not match definition ('int &' vs 'const int &')}}
}
-void A::f() {} // expected-error{{out-of-line definition of 'f' does not match any declaration in namespace 'A'}}
+void A::f() {} // expected-error-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'$}}
void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does not match any declaration in namespace 'A'}}
@@ -286,3 +286,15 @@ protected:
template <typename T>
struct A2<T>::B::C; // expected-error {{no struct named 'C'}}
}
+
+namespace PR13033 {
+namespace NS {
+ int a; // expected-note {{'NS::a' declared here}}
+ int longer_b; //expected-note {{'NS::longer_b' declared here}}
+}
+
+// Suggest adding a namespace qualifier to both variable names even though one
+// is only a single character long.
+int foobar = a + longer_b; // expected-error {{use of undeclared identifier 'a'; did you mean 'NS::a'?}} \
+ // expected-error {{use of undeclared identifier 'longer_b'; did you mean 'NS::longer_b'?}}
+}
diff --git a/test/SemaCXX/no-rtti.cpp b/test/SemaCXX/no-rtti.cpp
new file mode 100644
index 000000000000..75167050dca2
--- /dev/null
+++ b/test/SemaCXX/no-rtti.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fno-rtti %s
+
+namespace std {
+ class type_info;
+}
+
+void f()
+{
+ (void)typeid(int); // expected-error {{cannot use typeid with -fno-rtti}}
+}
diff --git a/test/SemaCXX/nullptr.cpp b/test/SemaCXX/nullptr.cpp
index e3136039f425..d148f76698ec 100644
--- a/test/SemaCXX/nullptr.cpp
+++ b/test/SemaCXX/nullptr.cpp
@@ -33,8 +33,10 @@ nullptr_t f(nullptr_t null)
// Operators
(void)(null == nullptr);
(void)(null <= nullptr);
+ (void)(null == 0);
(void)(null == (void*)0);
(void)((void*)0 == nullptr);
+ (void)(null <= 0);
(void)(null <= (void*)0);
(void)((void*)0 <= nullptr);
(void)(0 == nullptr);
@@ -44,7 +46,7 @@ nullptr_t f(nullptr_t null)
(void)(1 > nullptr); // expected-error {{invalid operands to binary expression}}
(void)(1 != nullptr); // expected-error {{invalid operands to binary expression}}
(void)(1 + nullptr); // expected-error {{invalid operands to binary expression}}
- (void)(0 ? nullptr : 0); // expected-error {{non-pointer operand type 'int' incompatible with nullptr}}
+ (void)(0 ? nullptr : 0);
(void)(0 ? nullptr : (void*)0);
(void)(0 ? nullptr : A()); // expected-error {{non-pointer operand type 'A' incompatible with nullptr}}
(void)(0 ? A() : nullptr); // expected-error {{non-pointer operand type 'A' incompatible with nullptr}}
diff --git a/test/SemaCXX/offsetof-0x.cpp b/test/SemaCXX/offsetof-0x.cpp
new file mode 100644
index 000000000000..610d919c1af1
--- /dev/null
+++ b/test/SemaCXX/offsetof-0x.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -fsyntax-only -std=c++11 -verify %s -Winvalid-offsetof
+
+struct NonPOD {
+ virtual void f();
+ int m;
+};
+
+struct P {
+ NonPOD fieldThatPointsToANonPODType;
+};
+
+void f() {
+ int i = __builtin_offsetof(P, fieldThatPointsToANonPODType.m); // expected-warning{{offset of on non-standard-layout type 'P'}}
+}
+
+struct StandardLayout {
+ int x;
+ StandardLayout() {}
+};
+int o = __builtin_offsetof(StandardLayout, x); // no-warning
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index b5e121486621..615b10a43971 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -233,7 +233,7 @@ float* intref(const int&);
void intref_test() {
float* ir1 = intref(5);
- float* ir2 = intref(5.5); // expected-warning{{implicit conversion turns literal floating-point number into integer}}
+ float* ir2 = intref(5.5); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 5.5 to 5}}
}
void derived5(C&); // expected-note{{candidate function not viable: cannot bind base class object of type 'A' to derived class reference 'C &' for 1st argument}}
@@ -260,14 +260,12 @@ struct Z : X, Y { };
int& cvqual_subsume(X&); // expected-note{{candidate function}}
float& cvqual_subsume(const Y&); // expected-note{{candidate function}}
-int& cvqual_subsume2(const X&); // expected-note{{candidate function}}
-float& cvqual_subsume2(const volatile Y&); // expected-note{{candidate function}}
-
-Z get_Z();
+int& cvqual_subsume2(X&); // expected-note{{candidate function}}
+float& cvqual_subsume2(volatile Y&); // expected-note{{candidate function}}
void cvqual_subsume_test(Z z) {
cvqual_subsume(z); // expected-error{{call to 'cvqual_subsume' is ambiguous}}
- int& x = cvqual_subsume2(get_Z()); // expected-error{{call to 'cvqual_subsume2' is ambiguous}}
+ cvqual_subsume2(z); // expected-error{{call to 'cvqual_subsume2' is ambiguous}}
}
// Test overloading with cv-qualification differences in reference
@@ -319,14 +317,20 @@ namespace PR5756 {
namespace test1 {
template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}}
void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}}
- void foo(int n); // expected-note {{candidate function not viable: requires 1 argument, but 2 were provided}}
- void foo(unsigned n = 10); // expected-note {{candidate function not viable: requires at most 1 argument, but 2 were provided}}
void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}}
void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
+ // PR 11857
+ void foo(int n); // expected-note {{candidate function not viable: requires single argument 'n', but 2 arguments were provided}}
+ void foo(unsigned n = 10); // expected-note {{candidate function not viable: allows at most single argument 'n', but 2 arguments were provided}}
+ void bar(int n, int u = 0); // expected-note {{candidate function not viable: requires at least argument 'n', but no arguments were provided}}
+ void baz(int n = 0, int u = 0); // expected-note {{candidate function not viable: requires at most 2 arguments, but 3 were provided}}
+
void test() {
foo(4, "hello"); //expected-error {{no matching function for call to 'foo'}}
+ bar(); //expected-error {{no matching function for call to 'bar'}}
+ baz(3, 4, 5); // expected-error {{no matching function for call to 'baz'}}
}
}
@@ -438,10 +442,10 @@ namespace PR6078 {
namespace PR6177 {
struct String { String(char const*); };
- void f(bool const volatile&); // expected-note{{passing argument to parameter here}}
- void f(String);
+ void f(bool const volatile&);
+ int &f(String);
- void g() { f(""); } // expected-error{{volatile lvalue reference to type 'const volatile bool' cannot bind to a value of unrelated type 'const char [1]'}}
+ void g() { int &r = f(""); }
}
namespace PR7095 {
@@ -568,3 +572,11 @@ namespace PR12142 {
void fun(int (*x)[10]); // expected-note{{candidate function not viable: 1st argument ('const int (*)[10]') would lose const qualifier}}
void g() { fun((const int(*)[10])0); } // expected-error{{no matching function for call to 'fun'}}
}
+
+// DR1152: Take 'volatile' into account when handling reference bindings in
+// overload resolution.
+namespace PR12931 {
+ void f(const int &, ...);
+ void f(const volatile int &, int);
+ void g() { f(0, 0); }
+}
diff --git a/test/SemaCXX/overload-member-call.cpp b/test/SemaCXX/overload-member-call.cpp
index 37c955201a98..09586201e561 100644
--- a/test/SemaCXX/overload-member-call.cpp
+++ b/test/SemaCXX/overload-member-call.cpp
@@ -72,8 +72,6 @@ namespace test1 {
class A {
template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}}
void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}}
- void foo(int n); // expected-note {{candidate function not viable: requires 1 argument, but 2 were provided}}
- void foo(unsigned n = 10); // expected-note {{candidate function not viable: requires at most 1 argument, but 2 were provided}}
void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}}
void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
@@ -83,6 +81,14 @@ namespace test1 {
void baz(A &d); // expected-note {{candidate function not viable: 1st argument ('const test1::A') would lose const qualifier}}
void baz(int i); // expected-note {{candidate function not viable: no known conversion from 'const test1::A' to 'int' for 1st argument}}
+
+ // PR 11857
+ void foo(int n); // expected-note {{candidate function not viable: requires single argument 'n', but 2 arguments were provided}}
+ void foo(unsigned n = 10); // expected-note {{candidate function not viable: allows at most single argument 'n', but 2 arguments were provided}}
+ void rab(double n, int u = 0); // expected-note {{candidate function not viable: requires at least argument 'n', but no arguments were provided}}
+ void rab(int n, int u = 0); // expected-note {{candidate function not viable: requires at least argument 'n', but no arguments were provided}}
+ void zab(double n = 0.0, int u = 0); // expected-note {{candidate function not viable: requires at most 2 arguments, but 3 were provided}}
+ void zab(int n = 0, int u = 0); // expected-note {{candidate function not viable: requires at most 2 arguments, but 3 were provided}}
};
void test() {
@@ -93,6 +99,9 @@ namespace test1 {
b.bar(0); //expected-error {{no matching member function for call to 'bar'}}
a.baz(b); //expected-error {{no matching member function for call to 'baz'}}
+
+ a.rab(); //expected-error {{no matching member function for call to 'rab'}}
+ a.zab(3, 4, 5); //expected-error {{no matching member function for call to 'zab'}}
}
}
diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp
index b3c08085a695..ac110a3c0561 100644
--- a/test/SemaCXX/overloaded-builtin-operators.cpp
+++ b/test/SemaCXX/overloaded-builtin-operators.cpp
@@ -174,7 +174,7 @@ void test_dr425(A a) {
// FIXME: lots of candidates here!
(void)(1.0f * a); // expected-error{{ambiguous}} \
// expected-note 4{{candidate}} \
- // expected-note {{remaining 77 candidates omitted; pass -fshow-overloads=all to show them}}
+ // expected-note {{remaining 117 candidates omitted; pass -fshow-overloads=all to show them}}
}
// pr5432
@@ -237,3 +237,34 @@ namespace PR7851 {
(void)(x - x);
}
}
+
+namespace PR12854 {
+ enum { size = 1 };
+ void plus_equals() {
+ int* __restrict py;
+ py += size;
+ }
+
+ struct RestrictInt {
+ operator int* __restrict &();
+ };
+
+ void user_conversions(RestrictInt ri) {
+ ++ri;
+ --ri;
+ ri++;
+ ri--;
+ }
+}
+
+namespace PR12964 {
+ struct X { operator __int128() const; } x;
+ bool a = x == __int128(0);
+ bool b = x == 0;
+
+ struct Y { operator unsigned __int128() const; } y;
+ bool c = y == __int128(0);
+ bool d = y == 0;
+
+ bool e = x == y;
+}
diff --git a/test/SemaCXX/pr13353.cpp b/test/SemaCXX/pr13353.cpp
new file mode 100644
index 000000000000..8fb5443fe623
--- /dev/null
+++ b/test/SemaCXX/pr13353.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+struct foo {
+ virtual void bar() ;
+};
+template<typename T>
+class zed : public foo {
+};
+template<typename T>
+class bah : public zed<T> {
+ void f() {
+ const_cast<foo *>(this->g())->bar();
+ }
+};
diff --git a/test/SemaCXX/pr13394-crash-on-invalid.cpp b/test/SemaCXX/pr13394-crash-on-invalid.cpp
new file mode 100644
index 000000000000..413c52af858c
--- /dev/null
+++ b/test/SemaCXX/pr13394-crash-on-invalid.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// Don't crash (PR13394).
+
+namespace stretch_v1 {
+ struct closure_t {
+ const stretch_v1::ops_t* d_methods; // expected-error {{no type named 'ops_t' in namespace 'stretch_v1'}}
+ };
+}
+namespace gatekeeper_v1 {
+ namespace gatekeeper_factory_v1 {
+ struct closure_t { // expected-note {{'closure_t' declared here}}
+ gatekeeper_v1::closure_t* create(); // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean 'closure_t'?}}
+ };
+ }
+ gatekeeper_v1::closure_t *x; // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1}}
+}
diff --git a/test/SemaCXX/printf-block.cpp b/test/SemaCXX/printf-block.cpp
new file mode 100644
index 000000000000..4a580037e731
--- /dev/null
+++ b/test/SemaCXX/printf-block.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wformat -verify %s -Wno-error=non-pod-varargs
+
+int (^block) (int, const char *,...) __attribute__((__format__(__printf__,2,3))) = ^ __attribute__((__format__(__printf__,2,3))) (int arg, const char *format,...) {return 5;};
+
+class HasNoCStr {
+ const char *str;
+ public:
+ HasNoCStr(const char *s): str(s) { }
+ const char *not_c_str() {return str;}
+};
+
+void test_block() {
+ const char str[] = "test";
+ HasNoCStr hncs(str);
+ int n = 4;
+ block(n, "%s %d", str, n); // no-warning
+ block(n, "%s %s", hncs, n); // expected-warning{{cannot pass non-POD object of type 'HasNoCStr' to variadic block; expected type from format string was 'char *'}} expected-warning{{format specifies type 'char *' but the argument has type 'int'}}
+}
diff --git a/test/SemaCXX/printf-cstr.cpp b/test/SemaCXX/printf-cstr.cpp
new file mode 100644
index 000000000000..a7eeb06b9c0e
--- /dev/null
+++ b/test/SemaCXX/printf-cstr.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -Wformat -verify %s -Wno-error=non-pod-varargs
+
+#include <stdarg.h>
+
+extern "C" {
+extern int printf(const char *restrict, ...);
+extern int sprintf(char *, const char *restrict, ...);
+}
+
+class HasCStr {
+ const char *str;
+ public:
+ HasCStr(const char *s): str(s) { }
+ const char *c_str() {return str;}
+};
+
+class HasNoCStr {
+ const char *str;
+ public:
+ HasNoCStr(const char *s): str(s) { }
+ const char *not_c_str() {return str;}
+};
+
+extern const char extstr[16];
+void pod_test() {
+ char str[] = "test";
+ char dest[32];
+ char formatString[] = "non-const %s %s";
+ HasCStr hcs(str);
+ HasNoCStr hncs(str);
+ int n = 10;
+
+ printf("%d: %s\n", n, hcs.c_str());
+ printf("%d: %s\n", n, hcs); // expected-warning{{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}}
+ printf("%d: %s\n", n, hncs); // expected-warning{{cannot pass non-POD object of type 'HasNoCStr' to variadic function; expected type from format string was 'char *'}}
+ sprintf(str, "%d: %s", n, hcs); // expected-warning{{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}}
+
+ printf(formatString, hcs, hncs); // expected-warning{{cannot pass object of non-POD type 'HasCStr' through variadic function}} expected-warning{{cannot pass object of non-POD type 'HasNoCStr' through variadic function}}
+ printf(extstr, hcs, n); // expected-warning{{cannot pass object of non-POD type 'HasCStr' through variadic function}}
+}
+
+struct Printf {
+ Printf();
+ Printf(const Printf&);
+ Printf(const char *,...) __attribute__((__format__(__printf__,2,3)));
+};
+
+void constructor_test() {
+ const char str[] = "test";
+ HasCStr hcs(str);
+ Printf p("%s %d %s", str, 10, 10); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
+ Printf q("%s %d", hcs, 10); // expected-warning {{cannot pass non-POD object of type 'HasCStr' to variadic constructor; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}}
+}
diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp
index d65a4684e629..a14193cc7ac8 100644
--- a/test/SemaCXX/qualified-id-lookup.cpp
+++ b/test/SemaCXX/qualified-id-lookup.cpp
@@ -86,14 +86,15 @@ namespace a {
namespace a {
namespace a { // A1
namespace a { // A2
- int i;
+ int i; // expected-note{{'::a::a::a::i' declared here}}
}
}
}
void test_a() {
- a::a::i = 3; // expected-error{{no member named 'i'}}
+ a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'; did you mean '::a::a::a::i'?}}
a::a::a::i = 4;
+ a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'$}}
}
struct Undef { // expected-note{{definition of 'Undef' is not complete until the closing '}'}}
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
index 7f41b93a46e4..a4bc4325e655 100644
--- a/test/SemaCXX/reinterpret-cast.cpp
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding -Wundefined-reinterpret-cast %s
+// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding -Wundefined-reinterpret-cast -Wno-unused-volatile-lvalue %s
#include <stdint.h>
diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp
index 364e4e4bef37..4a7560ba5b6a 100644
--- a/test/SemaCXX/static-assert.cpp
+++ b/test/SemaCXX/static-assert.cpp
@@ -34,3 +34,17 @@ static_assert(false, u"\U000317FF"); // expected-error {{static_assert failed u"
static_assert(false, u8"Ω"); // expected-error {{static_assert failed u8"\316\251"}}
static_assert(false, L"\u1234"); // expected-error {{static_assert failed L"\x1234"}}
static_assert(false, L"\x1ff" "0\x123" "fx\xfffff" "goop"); // expected-error {{static_assert failed L"\x1FF""0\x123""fx\xFFFFFgoop"}}
+
+template<typename T> struct AlwaysFails {
+ // Only give one error here.
+ static_assert(false, ""); // expected-error {{static_assert failed}}
+};
+AlwaysFails<int> alwaysFails;
+
+template<typename T> struct StaticAssertProtected {
+ static_assert(__is_literal(T), ""); // expected-error {{static_assert failed}}
+ static constexpr T t = {}; // no error here
+};
+struct X { ~X(); };
+StaticAssertProtected<int> sap1;
+StaticAssertProtected<X> sap2; // expected-note {{instantiation}}
diff --git a/test/SemaCXX/switch-implicit-fallthrough-cxx98.cpp b/test/SemaCXX/switch-implicit-fallthrough-cxx98.cpp
new file mode 100644
index 000000000000..14ffcef704d9
--- /dev/null
+++ b/test/SemaCXX/switch-implicit-fallthrough-cxx98.cpp
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -Wimplicit-fallthrough %s
+
+
+int fallthrough(int n) {
+ switch (n / 10) {
+ if (n - 1) {
+ n = 100;
+ } else if (n - 2) {
+ n = 101;
+ } else if (n - 3) {
+ n = 102;
+ }
+ case -1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}}
+ ;
+ case 0: {// expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}}
+ }
+ case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}}
+ n += 100 ;
+ case 3: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}}
+ if (n > 0)
+ n += 200;
+ case 4: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}}
+ if (n < 0)
+ ;
+ case 5: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}}
+ switch (n) {
+ case 111:
+ break;
+ case 112:
+ break;
+ case 113:
+ break ;
+ }
+ case 6: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}}
+ n += 300;
+ }
+ switch (n / 30) {
+ case 11:
+ case 12: // no warning here, intended fall-through, no statement between labels
+ n += 1600;
+ }
+ switch (n / 40) {
+ case 13:
+ if (n % 2 == 0) {
+ return 1;
+ } else {
+ return 2;
+ }
+ case 15: // no warning here, there's no fall-through
+ n += 3200;
+ }
+ switch (n / 50) {
+ case 17: {
+ if (n % 2 == 0) {
+ return 1;
+ } else {
+ return 2;
+ }
+ }
+ case 19: { // no warning here, there's no fall-through
+ n += 6400;
+ return 3;
+ }
+ case 21: { // no warning here, there's no fall-through
+ break;
+ }
+ case 23: // no warning here, there's no fall-through
+ n += 128000;
+ break;
+ case 25: // no warning here, there's no fall-through
+ break;
+ }
+
+ return n;
+}
+
+class ClassWithDtor {
+public:
+ ~ClassWithDtor() {}
+};
+
+void fallthrough2(int n) {
+ switch (n) {
+ case 0:
+ {
+ ClassWithDtor temp;
+ break;
+ }
+ default: // no warning here, there's no fall-through
+ break;
+ }
+}
+
+#define MY_SWITCH(X, Y, Z, U, V) switch (X) { case Y: Z; case U: V; }
+#define MY_SWITCH2(X, Y, Z) switch (X) { Y; Z; }
+#define MY_CASE(X, Y) case X: Y
+#define MY_CASE2(X, Y, U, V) case X: Y; case U: V
+
+int fallthrough_macro1(int n) {
+ MY_SWITCH(n, 13, n *= 2, 14, break) // expected-warning{{unannotated fall-through between switch labels}}
+
+ switch (n + 1) {
+ MY_CASE(33, n += 2);
+ MY_CASE(44, break); // expected-warning{{unannotated fall-through between switch labels}}
+ MY_CASE(55, n += 3);
+ }
+
+ switch (n + 3) {
+ MY_CASE(333, return 333);
+ MY_CASE2(444, n += 44, 4444, break); // expected-warning{{unannotated fall-through between switch labels}}
+ MY_CASE(555, n += 33);
+ }
+
+ MY_SWITCH2(n + 4, MY_CASE(17, n *= 3), MY_CASE(19, break)) // expected-warning{{unannotated fall-through between switch labels}}
+
+ MY_SWITCH2(n + 5, MY_CASE(21, break), MY_CASE2(23, n *= 7, 25, break)) // expected-warning{{unannotated fall-through between switch labels}}
+
+ return n;
+}
diff --git a/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp b/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
new file mode 100644
index 000000000000..7c52e5138b71
--- /dev/null
+++ b/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough-per-function %s
+
+
+int fallthrough(int n) {
+ switch (n / 10) {
+ case 0:
+ n += 100;
+ case 1: // expected-warning{{unannotated fall-through}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ switch (n) {
+ case 111:
+ n += 111;
+ [[clang::fallthrough]];
+ case 112:
+ n += 112;
+ case 113: // expected-warning{{unannotated fall-through}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ n += 113;
+ break ;
+ }
+ }
+ return n;
+}
+
+int fallthrough2(int n) {
+ switch (n / 10) {
+ case 0:
+ n += 100;
+ case 1: // no warning, as we didn't "opt-in" for it in this method
+ switch (n) {
+ case 111:
+ n += 111;
+ case 112: // no warning, as we didn't "opt-in" for it in this method
+ n += 112;
+ case 113: // no warning, as we didn't "opt-in" for it in this method
+ n += 113;
+ break ;
+ }
+ }
+ return n;
+}
+
+void unscoped(int n) {
+ switch (n % 2) {
+ case 0:
+ // FIXME: This should be typo-corrected, probably.
+ [[fallthrough]];
+ case 2: // expected-warning{{unannotated fall-through}} expected-note{{clang::fallthrough}} expected-note{{break;}}
+ [[clang::fallthrough]];
+ case 1:
+ break;
+ }
+}
diff --git a/test/SemaCXX/switch-implicit-fallthrough.cpp b/test/SemaCXX/switch-implicit-fallthrough.cpp
new file mode 100644
index 000000000000..cfc29c237c2d
--- /dev/null
+++ b/test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -0,0 +1,197 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough %s
+
+
+int fallthrough(int n) {
+ switch (n / 10) {
+ if (n - 1) {
+ n = 100;
+ } else if (n - 2) {
+ n = 101;
+ } else if (n - 3) {
+ n = 102;
+ }
+ case -1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ ;
+ case 0: {// expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ }
+ case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ n += 100 ;
+ case 3: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ if (n > 0)
+ n += 200;
+ case 4: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ if (n < 0)
+ ;
+ case 5: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ switch (n) {
+ case 111:
+ break;
+ case 112:
+ break;
+ case 113:
+ break ;
+ }
+ case 6: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ n += 300;
+ case 66: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}}
+ break;
+ }
+ switch (n / 20) {
+ case 7:
+ n += 400;
+ [[clang::fallthrough]];
+ case 9: // no warning here, intended fall-through marked with an attribute
+ n += 800;
+ [[clang::fallthrough]];
+ default: { // no warning here, intended fall-through marked with an attribute
+ if (n % 2 == 0) {
+ return 1;
+ } else {
+ [[clang::fallthrough]];
+ }
+ }
+ case 10: // no warning here, intended fall-through marked with an attribute
+ if (n % 3 == 0) {
+ n %= 3;
+ } else {
+ [[clang::fallthrough]];
+ }
+ case 110: // expected-warning{{unannotated fall-through between switch labels}} but no fix-it hint as we have one fall-through annotation!
+ n += 800;
+ }
+ switch (n / 30) {
+ case 11:
+ case 12: // no warning here, intended fall-through, no statement between labels
+ n += 1600;
+ }
+ switch (n / 40) {
+ case 13:
+ if (n % 2 == 0) {
+ return 1;
+ } else {
+ return 2;
+ }
+ case 15: // no warning here, there's no fall-through
+ n += 3200;
+ }
+ switch (n / 50) {
+ case 17: {
+ if (n % 2 == 0) {
+ return 1;
+ } else {
+ return 2;
+ }
+ }
+ case 19: { // no warning here, there's no fall-through
+ n += 6400;
+ return 3;
+ }
+ case 21: { // no warning here, there's no fall-through
+ break;
+ }
+ case 23: // no warning here, there's no fall-through
+ n += 128000;
+ break;
+ case 25: // no warning here, there's no fall-through
+ break;
+ }
+
+ return n;
+}
+
+class ClassWithDtor {
+public:
+ ~ClassWithDtor() {}
+};
+
+void fallthrough2(int n) {
+ switch (n) {
+ case 0:
+ {
+ ClassWithDtor temp;
+ break;
+ }
+ default: // no warning here, there's no fall-through
+ break;
+ }
+}
+
+#define MY_SWITCH(X, Y, Z, U, V) switch (X) { case Y: Z; case U: V; }
+#define MY_SWITCH2(X, Y, Z) switch (X) { Y; Z; }
+#define MY_CASE(X, Y) case X: Y
+#define MY_CASE2(X, Y, U, V) case X: Y; case U: V
+
+int fallthrough_macro1(int n) {
+ MY_SWITCH(n, 13, n *= 2, 14, break) // expected-warning{{unannotated fall-through between switch labels}}
+
+ switch (n + 1) {
+ MY_CASE(33, n += 2);
+ MY_CASE(44, break); // expected-warning{{unannotated fall-through between switch labels}}
+ MY_CASE(55, n += 3);
+ }
+
+ switch (n + 3) {
+ MY_CASE(333, return 333);
+ MY_CASE2(444, n += 44, 4444, break); // expected-warning{{unannotated fall-through between switch labels}}
+ MY_CASE(555, n += 33);
+ }
+
+ MY_SWITCH2(n + 4, MY_CASE(17, n *= 3), MY_CASE(19, break)) // expected-warning{{unannotated fall-through between switch labels}}
+
+ MY_SWITCH2(n + 5, MY_CASE(21, break), MY_CASE2(23, n *= 7, 25, break)) // expected-warning{{unannotated fall-through between switch labels}}
+
+ return n;
+}
+
+int fallthrough_position(int n) {
+ switch (n) {
+ [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}}
+ case 221:
+ [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
+ return 1;
+ [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}}
+ case 222:
+ [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
+ n += 400;
+ case 223: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+ [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
+ }
+
+ // TODO: uncomment this test after CFG gets more options to deal with
+ // unreachable code:
+ // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20120507/057370.html
+#if 0
+ long p = static_cast<long>(n) * n;
+ switch (sizeof(p)) {
+ case 9: // this test will not work on compilers with 72-bit long
+ n += static_cast<int>(p >> 32);
+ [[clang::fallthrough]]; // no warning here
+ case 5: // it is not intended to work on compilers with 40-bit long as well
+ n += static_cast<int>(p);
+ break;
+ default:
+ break;
+ }
+#endif
+
+ return n;
+}
+
+int fallthrough_targets(int n) {
+ [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}}
+
+ [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}}
+ switch (n) {
+ case 121:
+ n += 400;
+ [[clang::fallthrough]]; // no warning here, correct target
+ case 123:
+ [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}}
+ n += 800;
+ break;
+ [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} expected-note{{did you forget ';'?}}
+ case 125:
+ n += 1600;
+ }
+ return n;
+}
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index f53939ac1790..54294bcbb8b1 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -131,25 +131,25 @@ void is_pod()
{ int arr[T(__is_pod(HasAnonymousUnion))]; }
{ int arr[T(__is_pod(Vector))]; }
{ int arr[T(__is_pod(VectorExt))]; }
+ { int arr[T(__is_pod(Derives))]; }
+ { int arr[T(__is_pod(DerivesAr))]; }
+ { int arr[T(__is_pod(DerivesArNB))]; }
+ { int arr[T(__is_pod(DerivesEmpty))]; }
+ { int arr[T(__is_pod(HasPriv))]; }
+ { int arr[T(__is_pod(HasProt))]; }
+ { int arr[T(__is_pod(DerivesHasPriv))]; }
+ { int arr[T(__is_pod(DerivesHasProt))]; }
- { int arr[F(__is_pod(Derives))]; }
- { int arr[F(__is_pod(DerivesAr))]; }
- { int arr[F(__is_pod(DerivesArNB))]; }
- { int arr[F(__is_pod(DerivesEmpty))]; }
{ int arr[F(__is_pod(HasCons))]; }
{ int arr[F(__is_pod(HasCopyAssign))]; }
{ int arr[F(__is_pod(HasMoveAssign))]; }
{ int arr[F(__is_pod(HasDest))]; }
- { int arr[F(__is_pod(HasPriv))]; }
- { int arr[F(__is_pod(HasProt))]; }
{ int arr[F(__is_pod(HasRef))]; }
{ int arr[F(__is_pod(HasVirt))]; }
{ int arr[F(__is_pod(DerivesHasCons))]; }
{ int arr[F(__is_pod(DerivesHasCopyAssign))]; }
{ int arr[F(__is_pod(DerivesHasMoveAssign))]; }
{ int arr[F(__is_pod(DerivesHasDest))]; }
- { int arr[F(__is_pod(DerivesHasPriv))]; }
- { int arr[F(__is_pod(DerivesHasProt))]; }
{ int arr[F(__is_pod(DerivesHasRef))]; }
{ int arr[F(__is_pod(DerivesHasVirt))]; }
{ int arr[F(__is_pod(NonPOD))]; }
@@ -1223,10 +1223,10 @@ void has_trivial_copy_constructor() {
{ int arr[T(__has_trivial_copy(const Int))]; }
{ int arr[T(__has_trivial_copy(AllDefaulted))]; }
{ int arr[T(__has_trivial_copy(AllDeleted))]; }
+ { int arr[T(__has_trivial_copy(DerivesAr))]; }
{ int arr[F(__has_trivial_copy(HasCopy))]; }
{ int arr[F(__has_trivial_copy(HasTemplateCons))]; }
- { int arr[F(__has_trivial_copy(DerivesAr))]; }
{ int arr[F(__has_trivial_copy(VirtAr))]; }
{ int arr[F(__has_trivial_copy(void))]; }
{ int arr[F(__has_trivial_copy(cvoid))]; }
@@ -1250,13 +1250,13 @@ void has_trivial_copy_assignment() {
{ int arr[T(__has_trivial_assign(HasMoveAssign))]; }
{ int arr[T(__has_trivial_assign(AllDefaulted))]; }
{ int arr[T(__has_trivial_assign(AllDeleted))]; }
+ { int arr[T(__has_trivial_assign(DerivesAr))]; }
{ int arr[F(__has_trivial_assign(IntRef))]; }
{ int arr[F(__has_trivial_assign(HasCopyAssign))]; }
{ int arr[F(__has_trivial_assign(const Int))]; }
{ int arr[F(__has_trivial_assign(ConstIntAr))]; }
{ int arr[F(__has_trivial_assign(ConstIntArAr))]; }
- { int arr[F(__has_trivial_assign(DerivesAr))]; }
{ int arr[F(__has_trivial_assign(VirtAr))]; }
{ int arr[F(__has_trivial_assign(void))]; }
{ int arr[F(__has_trivial_assign(cvoid))]; }
@@ -1338,6 +1338,7 @@ void has_nothrow_assign() {
{ int arr[T(__has_nothrow_assign(HasVirtDest))]; }
{ int arr[T(__has_nothrow_assign(AllPrivate))]; }
{ int arr[T(__has_nothrow_assign(UsingAssign))]; }
+ { int arr[T(__has_nothrow_assign(DerivesAr))]; }
{ int arr[F(__has_nothrow_assign(IntRef))]; }
{ int arr[F(__has_nothrow_assign(HasCopyAssign))]; }
@@ -1345,7 +1346,6 @@ void has_nothrow_assign() {
{ int arr[F(__has_nothrow_assign(const Int))]; }
{ int arr[F(__has_nothrow_assign(ConstIntAr))]; }
{ int arr[F(__has_nothrow_assign(ConstIntArAr))]; }
- { int arr[F(__has_nothrow_assign(DerivesAr))]; }
{ int arr[F(__has_nothrow_assign(VirtAr))]; }
{ int arr[F(__has_nothrow_assign(void))]; }
{ int arr[F(__has_nothrow_assign(cvoid))]; }
@@ -1375,18 +1375,15 @@ void has_nothrow_copy() {
{ int arr[T(__has_nothrow_copy(HasVirtDest))]; }
{ int arr[T(__has_nothrow_copy(HasTemplateCons))]; }
{ int arr[T(__has_nothrow_copy(AllPrivate))]; }
+ { int arr[T(__has_nothrow_copy(DerivesAr))]; }
{ int arr[F(__has_nothrow_copy(HasCopy))]; }
{ int arr[F(__has_nothrow_copy(HasMultipleCopy))]; }
- { int arr[F(__has_nothrow_copy(DerivesAr))]; }
{ int arr[F(__has_nothrow_copy(VirtAr))]; }
{ int arr[F(__has_nothrow_copy(void))]; }
{ int arr[F(__has_nothrow_copy(cvoid))]; }
}
-template<bool b> struct assert_expr;
-template<> struct assert_expr<true> {};
-
void has_nothrow_constructor() {
{ int arr[T(__has_nothrow_constructor(Int))]; }
{ int arr[T(__has_nothrow_constructor(IntAr))]; }
@@ -1415,11 +1412,6 @@ void has_nothrow_constructor() {
{ int arr[F(__has_nothrow_constructor(void))]; }
{ int arr[F(__has_nothrow_constructor(cvoid))]; }
{ int arr[F(__has_nothrow_constructor(HasTemplateCons))]; }
-
- // While parsing an in-class initializer, the constructor is not known to be
- // non-throwing yet.
- struct HasInClassInit { int n = (assert_expr<!__has_nothrow_constructor(HasInClassInit)>(), 0); };
- { int arr[T(__has_nothrow_constructor(HasInClassInit))]; }
}
void has_virtual_destructor() {
@@ -1582,6 +1574,8 @@ struct X0 {
template<typename U> X0(const X0<U>&);
};
+struct Abstract { virtual void f() = 0; };
+
void is_convertible_to() {
{ int arr[T(__is_convertible_to(Int, Int))]; }
{ int arr[F(__is_convertible_to(Int, IntAr))]; }
@@ -1606,6 +1600,7 @@ void is_convertible_to() {
{ int arr[F(__is_convertible_to(Function, Function))]; }
{ int arr[F(__is_convertible_to(PrivateCopy, PrivateCopy))]; }
{ int arr[T(__is_convertible_to(X0<int>, X0<float>))]; }
+ { int arr[F(__is_convertible_to(Abstract, Abstract))]; }
}
namespace is_convertible_to_instantiate {
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index b1e8d91d450d..893f08a422ca 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -190,3 +190,47 @@ namespace test1 {
};
test1::FooBar *b; // expected-error{{no type named 'FooBar' in namespace 'test1'; did you mean 'Foobar'?}}
}
+
+namespace ImplicitInt {
+ void f(int, unsinged); // expected-error{{did you mean 'unsigned'}}
+ struct S {
+ unsinged : 4; // expected-error{{did you mean 'unsigned'}}
+ };
+}
+
+namespace PR12951 {
+// If there are two corrections that have the same identifier and edit distance
+// and only differ by their namespaces, don't suggest either as a correction
+// since both are equally likely corrections.
+namespace foobar { struct Thing {}; }
+namespace bazquux { struct Thing {}; }
+void f() { Thing t; } // expected-error{{unknown type name 'Thing'}}
+}
+
+namespace PR13051 {
+ template<typename T> struct S {
+ template<typename U> void f();
+ operator bool() const;
+ };
+
+ void f() {
+ f(&S<int>::tempalte f<int>); // expected-error{{did you mean 'template'?}}
+ f(&S<int>::opeartor bool); // expected-error{{did you mean 'operator'?}}
+ f(&S<int>::foo); // expected-error-re{{no member named 'foo' in 'PR13051::S<int>'$}}
+ }
+}
+
+namespace PR6325 {
+class foo { }; // expected-note{{'foo' declared here}}
+// Note that for this example (pulled from the PR), if keywords are not excluded
+// as correction candidates then no suggestion would be given; correcting
+// 'boo' to 'bool' is the same edit distance as correcting 'boo' to 'foo'.
+class bar : boo { }; // expected-error{{unknown class name 'boo'; did you mean 'foo'?}}
+}
+
+namespace bogus_keyword_suggestion {
+void test() {
+ status = "OK"; // expected-error-re{{use of undeclared identifier 'status'$}}
+ return status; // expected-error-re{{use of undeclared identifier 'status'$}}
+ }
+}
diff --git a/test/SemaCXX/uninit-variables.cpp b/test/SemaCXX/uninit-variables.cpp
index eb6428d631f2..687bfd2638d4 100644
--- a/test/SemaCXX/uninit-variables.cpp
+++ b/test/SemaCXX/uninit-variables.cpp
@@ -141,3 +141,9 @@ void test_bitcasts_2() {
int y = (float &)x; // expected-warning {{uninitialized when used here}}
}
+void consume_const_ref(const int &n);
+int test_const_ref() {
+ int n; // expected-note {{variable}}
+ consume_const_ref(n);
+ return n; // expected-warning {{uninitialized when used here}}
+}
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index 7879e7c7531f..13d287bf1af6 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wuninitialized -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wuninitialized -Wno-unused-value -std=c++11 -verify %s
int foo(int x);
int bar(int* x);
@@ -10,9 +10,6 @@ int far(const int& x);
int a = a; // no-warning: used to signal intended lack of initialization.
int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
int c = (c + c); // expected-warning 2 {{variable 'c' is uninitialized when used within its own initialization}}
-void test() {
- int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}}
-}
int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
@@ -24,6 +21,51 @@ int i = boo(i);
int j = far(j);
int k = __alignof__(k);
+int l = k ? l : l; // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
+int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
+int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+
+void test_stuff () {
+ int a = a; // no-warning: used to signal intended lack of initialization.
+ int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
+ int c = (c + c); // expected-warning {{variable 'c' is uninitialized when used within its own initialization}}
+ int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}}
+ int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
+ int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+
+ // Thes don't warn as they don't require the value.
+ int g = sizeof(g);
+ void* ptr = &ptr;
+ int h = bar(&h);
+ int i = boo(i);
+ int j = far(j);
+ int k = __alignof__(k);
+
+ int l = k ? l : l; // FIXME: warn here
+ int m = 1 + (k ? m : m); // FIXME: warn here
+ int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+
+ for (;;) {
+ int a = a; // no-warning: used to signal intended lack of initialization.
+ int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
+ int c = (c + c); // expected-warning {{variable 'c' is uninitialized when used within its own initialization}}
+ int d = ({ d + d ;}); // expected-warning {{variable 'd' is uninitialized when used within its own initialization}}
+ int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
+ int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+
+ // Thes don't warn as they don't require the value.
+ int g = sizeof(g);
+ void* ptr = &ptr;
+ int h = bar(&h);
+ int i = boo(i);
+ int j = far(j);
+ int k = __alignof__(k);
+
+ int l = k ? l : l; // FIXME: warn here
+ int m = 1 + (k ? m : m); // FIXME: warn here
+ int n = -n; // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+ }
+}
// Test self-references with record types.
class A {
@@ -48,8 +90,9 @@ class A {
A getA() { return A(); }
A getA(int x) { return A(); }
A getA(A* a) { return A(); }
+A getA(A a) { return A(); }
-void setupA() {
+void setupA(bool x) {
A a1;
a1.set(a1.get());
A a2(a1.get());
@@ -69,8 +112,33 @@ void setupA() {
A a15 = getA(a15.num); // expected-warning {{variable 'a15' is uninitialized when used within its own initialization}}
A a16(&a16.num); // expected-warning {{variable 'a16' is uninitialized when used within its own initialization}}
A a17(a17.get2()); // expected-warning {{variable 'a17' is uninitialized when used within its own initialization}}
+ A a18 = x ? a18 : a17; // expected-warning {{variable 'a18' is uninitialized when used within its own initialization}}
+ A a19 = getA(x ? a19 : a17); // expected-warning {{variable 'a19' is uninitialized when used within its own initialization}}
}
+bool x;
+
+A a1;
+A a2(a1.get());
+A a3(a1);
+A a4(&a4);
+A a5(a5.zero());
+A a6(a6.ONE);
+A a7 = getA();
+A a8 = getA(a8.TWO);
+A a9 = getA(&a9);
+A a10(a10.count);
+
+A a11(a11); // expected-warning {{variable 'a11' is uninitialized when used within its own initialization}}
+A a12(a12.get()); // expected-warning {{variable 'a12' is uninitialized when used within its own initialization}}
+A a13(a13.num); // expected-warning {{variable 'a13' is uninitialized when used within its own initialization}}
+A a14 = A(a14); // expected-warning {{variable 'a14' is uninitialized when used within its own initialization}}
+A a15 = getA(a15.num); // expected-warning {{variable 'a15' is uninitialized when used within its own initialization}}
+A a16(&a16.num); // expected-warning {{variable 'a16' is uninitialized when used within its own initialization}}
+A a17(a17.get2()); // expected-warning {{variable 'a17' is uninitialized when used within its own initialization}}
+A a18 = x ? a18 : a17; // expected-warning {{variable 'a18' is uninitialized when used within its own initialization}}
+A a19 = getA(x ? a19 : a17); // expected-warning {{variable 'a19' is uninitialized when used within its own initialization}}
+
struct B {
// POD struct.
int x;
@@ -97,6 +165,7 @@ void setupB() {
B b7(b7); // expected-warning {{variable 'b7' is uninitialized when used within its own initialization}}
B b8 = getB(b8.x); // expected-warning {{variable 'b8' is uninitialized when used within its own initialization}}
B b9 = getB(b9.y); // expected-warning {{variable 'b9' is uninitialized when used within its own initialization}}
+ B b10 = getB(-b10.x); // expected-warning {{variable 'b10' is uninitialized when used within its own initialization}}
}
// Also test similar constructs in a field's initializer.
@@ -106,9 +175,9 @@ struct S {
S(bool (*)[1]) : x(x) {} // expected-warning {{field is uninitialized when used here}}
S(bool (*)[2]) : x(x + 1) {} // expected-warning {{field is uninitialized when used here}}
- S(bool (*)[3]) : x(x + x) {} // expected-warning {{field is uninitialized when used here}}
+ S(bool (*)[3]) : x(x + x) {} // expected-warning 2{{field is uninitialized when used here}}
S(bool (*)[4]) : x(static_cast<long>(x) + 1) {} // expected-warning {{field is uninitialized when used here}}
- S(bool (*)[5]) : x(foo(x)) {} // FIXME: This should warn!
+ S(bool (*)[5]) : x(foo(x)) {} // expected-warning {{field is uninitialized when used here}}
// These don't actually require the value of x and so shouldn't warn.
S(char (*)[1]) : x(sizeof(x)) {} // rdar://8610363
@@ -164,6 +233,86 @@ int pr12325(int params) {
// Test lambda expressions with -Wuninitialized
int test_lambda() {
- auto f1 = [] (int x, int y) { int z; return x + y + z; }; // expected-warning {{C++11 requires lambda with omitted result type to consist of a single return statement}} expected-warning{{variable 'z' is uninitialized when used here}} expected-note {{initialize the variable 'z' to silence this warning}}
+ auto f1 = [] (int x, int y) { int z; return x + y + z; }; // expected-warning{{variable 'z' is uninitialized when used here}} expected-note {{initialize the variable 'z' to silence this warning}}
return f1(1, 2);
}
+
+namespace {
+ struct A {
+ enum { A1 };
+ static int A2() {return 5;}
+ int A3;
+ int A4() { return 5;}
+ };
+
+ struct B {
+ A a;
+ };
+
+ struct C {
+ C() {}
+ C(int x) {}
+ static A a;
+ B b;
+ };
+ A C::a = A();
+
+ // Accessing non-static members will give a warning.
+ struct D {
+ C c;
+ D(char (*)[1]) : c(c.b.a.A1) {}
+ D(char (*)[2]) : c(c.b.a.A2()) {}
+ D(char (*)[3]) : c(c.b.a.A3) {} // expected-warning {{field is uninitialized when used here}}
+ D(char (*)[4]) : c(c.b.a.A4()) {} // expected-warning {{field is uninitialized when used here}}
+
+ // c::a is static, so it is already initialized
+ D(char (*)[5]) : c(c.a.A1) {}
+ D(char (*)[6]) : c(c.a.A2()) {}
+ D(char (*)[7]) : c(c.a.A3) {}
+ D(char (*)[8]) : c(c.a.A4()) {}
+ };
+
+ struct E {
+ int a, b, c;
+ E(char (*)[1]) : a(a ? b : c) {} // expected-warning {{field is uninitialized when used here}}
+ E(char (*)[2]) : a(b ? a : a) {} // expected-warning 2{{field is uninitialized when used here}}
+ E(char (*)[3]) : a(b ? (a) : c) {} // expected-warning {{field is uninitialized when used here}}
+ E(char (*)[4]) : a(b ? c : (a+c)) {} // expected-warning {{field is uninitialized when used here}}
+ E(char (*)[5]) : a(b ? c : b) {}
+
+ E(char (*)[6]) : a(a ?: a) {} // expected-warning 2{{field is uninitialized when used here}}
+ E(char (*)[7]) : a(b ?: a) {} // expected-warning {{field is uninitialized when used here}}
+ E(char (*)[8]) : a(a ?: c) {} // expected-warning {{field is uninitialized when used here}}
+ E(char (*)[9]) : a(b ?: c) {}
+
+ E(char (*)[10]) : a((a, a, b)) {}
+ E(char (*)[11]) : a((c + a, a + 1, b)) {} // expected-warning 2{{field is uninitialized when used here}}
+ E(char (*)[12]) : a((b + c, c, a)) {} // expected-warning {{field is uninitialized when used here}}
+ E(char (*)[13]) : a((a, a, a, a)) {} // expected-warning {{field is uninitialized when used here}}
+ E(char (*)[14]) : a((b, c, c)) {}
+ };
+
+ struct F {
+ int a;
+ F* f;
+ F(int) {}
+ F() {}
+ };
+
+ int F::*ptr = &F::a;
+ F* F::*f_ptr = &F::f;
+ struct G {
+ F f1, f2;
+ F *f3, *f4;
+ G(char (*)[1]) : f1(f1) {} // expected-warning {{field is uninitialized when used here}}
+ G(char (*)[2]) : f2(f1) {}
+ G(char (*)[3]) : f2(F()) {}
+
+ G(char (*)[4]) : f1(f1.*ptr) {} // expected-warning {{field is uninitialized when used here}}
+ G(char (*)[5]) : f2(f1.*ptr) {}
+
+ G(char (*)[6]) : f3(f3) {} // expected-warning {{field is uninitialized when used here}}
+ G(char (*)[7]) : f3(f3->*f_ptr) {} // expected-warning {{field is uninitialized when used here}}
+ G(char (*)[8]) : f3(new F(f3->*ptr)) {} // expected-warning {{field is uninitialized when used here}}
+ };
+}
diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp
index 5f8d8caae698..893e0cc5dc86 100644
--- a/test/SemaCXX/unknown-type-name.cpp
+++ b/test/SemaCXX/unknown-type-name.cpp
@@ -20,6 +20,13 @@ struct A {
typedef T type;
type f();
+
+ type g();
+
+ static int n;
+ static type m;
+ static int h(T::type, int); // expected-error{{missing 'typename'}}
+ static int h(T::type x, char); // expected-error{{missing 'typename'}}
};
template<typename T>
@@ -27,3 +34,52 @@ A<T>::type g(T t) { return t; } // expected-error{{missing 'typename'}}
template<typename T>
A<T>::type A<T>::f() { return type(); } // expected-error{{missing 'typename'}}
+
+template<typename T>
+void f(T::type) { } // expected-error{{missing 'typename'}}
+
+template<typename T>
+void g(T::type x) { } // expected-error{{missing 'typename'}}
+
+template<typename T>
+void f(T::type, int) { } // expected-error{{missing 'typename'}}
+
+template<typename T>
+void f(T::type x, char) { } // expected-error{{missing 'typename'}}
+
+template<typename T>
+void f(int, T::type) { } // expected-error{{missing 'typename'}}
+
+template<typename T>
+void f(char, T::type x) { } // expected-error{{missing 'typename'}}
+
+template<typename T>
+void f(int, T::type, int) { } // expected-error{{missing 'typename'}}
+
+template<typename T>
+void f(int, T::type x, char) { } // expected-error{{missing 'typename'}}
+
+template<typename T> int A<T>::n(T::value); // ok
+template<typename T>
+A<T>::type // expected-error{{missing 'typename'}}
+A<T>::m(T::value, 0); // ok
+
+template<typename T> int A<T>::h(T::type, int) {} // expected-error{{missing 'typename'}}
+template<typename T> int A<T>::h(T::type x, char) {} // expected-error{{missing 'typename'}}
+
+template<typename T> int h(T::type, int); // expected-error{{missing 'typename'}}
+template<typename T> int h(T::type x, char); // expected-error{{missing 'typename'}}
+
+template<typename T> int junk1(T::junk); // expected-error{{declared as a template}}
+template<typename T> int junk2(T::junk) throw(); // expected-error{{missing 'typename'}}
+template<typename T> int junk3(T::junk) = delete; // expected-error{{missing 'typename'}} expected-warning{{C++11}}
+template<typename T> int junk4(T::junk j); // expected-error{{missing 'typename'}}
+
+// FIXME: We can tell this was intended to be a function because it does not
+// have a dependent nested name specifier.
+template<typename T> int i(T::type, int()); // expected-error{{variable 'i' declared as a template}}
+
+// FIXME: We know which type specifier should have been specified here. Provide
+// a fix-it to add 'typename A<T>::type'
+template<typename T>
+A<T>::g() { } // expected-error{{requires a type specifier}}
diff --git a/test/SemaCXX/unused.cpp b/test/SemaCXX/unused.cpp
index 88783ce1a6b3..54898c828ec6 100644
--- a/test/SemaCXX/unused.cpp
+++ b/test/SemaCXX/unused.cpp
@@ -1,24 +1,36 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+
// PR4103 : Make sure we don't get a bogus unused expression warning
-class APInt {
- char foo;
-};
-class APSInt : public APInt {
- char bar;
-public:
- APSInt &operator=(const APSInt &RHS);
-};
+namespace PR4103 {
+ class APInt {
+ char foo;
+ };
+ class APSInt : public APInt {
+ char bar;
+ public:
+ APSInt &operator=(const APSInt &RHS);
+ };
-APSInt& APSInt::operator=(const APSInt &RHS) {
- APInt::operator=(RHS);
- return *this;
-}
+ APSInt& APSInt::operator=(const APSInt &RHS) {
+ APInt::operator=(RHS);
+ return *this;
+ }
-template<typename T>
-struct X {
- X();
-};
+ template<typename T>
+ struct X {
+ X();
+ };
+
+ void test() {
+ X<int>();
+ }
+}
-void test() {
- X<int>();
+namespace derefvolatile {
+ void f(volatile char* x) {
+ *x; // expected-warning {{expression result unused; assign into a variable to force a volatile load}}
+ (void)*x; // expected-warning {{expression result unused; assign into a variable to force a volatile load}}
+ volatile char y = 10;
+ (void)y; // don't warn here, because it's a common pattern.
+ }
}
diff --git a/test/SemaCXX/user-defined-conversions.cpp b/test/SemaCXX/user-defined-conversions.cpp
index 43ec5a3d4ab9..284a31069288 100644
--- a/test/SemaCXX/user-defined-conversions.cpp
+++ b/test/SemaCXX/user-defined-conversions.cpp
@@ -69,7 +69,7 @@ void test_conversion(ConvertibleToBase ctb, ConvertibleToDerived ctd,
}
struct X1 {
- X1(X1&); // expected-note{{candidate constructor not viable: no known conversion from 'X1' to 'X1 &' for 1st argument}}
+ X1(X1&); // expected-note{{candidate constructor not viable: expects an l-value for 1st argument}}
};
struct X2 {
diff --git a/test/SemaCXX/virtuals.cpp b/test/SemaCXX/virtuals.cpp
index ea7d203ca70f..a340e9d86b65 100644
--- a/test/SemaCXX/virtuals.cpp
+++ b/test/SemaCXX/virtuals.cpp
@@ -30,7 +30,7 @@ A fn(A) // expected-error{{parameter type 'A' is an abstract class}} \
// expected-error{{return type 'A' is an abstract class}}
{
A a; // expected-error{{variable type 'A' is an abstract class}}
- (void)static_cast<A>(0);
+ (void)static_cast<A>(0); // expected-error{{allocating an object of abstract class type 'A'}}
try {
} catch(A) { // expected-error{{variable type 'A' is an abstract class}}
}
diff --git a/test/SemaCXX/warn-deprecated-header.cpp b/test/SemaCXX/warn-deprecated-header.cpp
index f6ac2cb6393a..015e7751b93a 100644
--- a/test/SemaCXX/warn-deprecated-header.cpp
+++ b/test/SemaCXX/warn-deprecated-header.cpp
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -fdeprecated-macro -verify %s
// RUN: %clang_cc1 -fsyntax-only -Werror %s
+// expected-warning@+2 {{This file is deprecated.}}
#ifdef __DEPRECATED
-#warning This file is deprecated. // expected-warning {{This file is deprecated.}}
+#warning This file is deprecated.
#endif
diff --git a/test/SemaCXX/warn-literal-conversion.cpp b/test/SemaCXX/warn-literal-conversion.cpp
index 5fcae5dc80e6..d7bec4c73e5b 100644
--- a/test/SemaCXX/warn-literal-conversion.cpp
+++ b/test/SemaCXX/warn-literal-conversion.cpp
@@ -5,29 +5,29 @@ void foo(int y);
// Warn when a literal float or double is assigned or bound to an integer.
void test0() {
// Float
- int y0 = 1.2222F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y1 = (1.2222F); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y2 = (((1.2222F))); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y3 = 12E-1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y4 = 1.23E1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ int y0 = 1.2222F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2222 to 1}}
+ int y1 = (1.2222F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2222 to 1}}
+ int y2 = (((1.2222F))); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2222 to 1}}
+ int y3 = 12E-1F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}}
+ int y4 = 1.23E1F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 12.3 to 12}}
// Double
- int y5 = 1.2222; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y6 = 12E-1; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y7 = 1.23E1; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y8 = (1.23E1); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ int y5 = 1.2222; // expected-warning {{implicit conversion from 'double' to 'int' changes value from 1.2222 to 1}}
+ int y6 = 12E-1; // expected-warning {{implicit conversion from 'double' to 'int' changes value from 1.2 to 1}}
+ int y7 = 1.23E1; // expected-warning {{implicit conversion from 'double' to 'int' changes value from 12.3 to 12}}
+ int y8 = (1.23E1); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 12.3 to 12}}
// Test assignment to an existing variable.
- y8 = 2.22F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ y8 = 2.22F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 2.22 to 2}}
// Test direct initialization.
- int y9(1.23F); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ int y9(1.23F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.23 to 1}}
// Test passing a literal floating-point value to a function that takes an integer.
- foo(1.2F); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ foo(1.2F); // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}}
- int y10 = -1.2F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ int y10 = -1.2F; // expected-warning {{implicit conversion from 'float' to 'int' changes value from 1.2 to 1}}
- // -Wconversion-literal does NOT catch const values.
+ // -Wliteral-conversion does NOT catch const values.
// (-Wconversion DOES catch them.)
static const float sales_tax_rate = .095F;
int z = sales_tax_rate;
diff --git a/test/SemaCXX/warn-loop-analysis.cpp b/test/SemaCXX/warn-loop-analysis.cpp
new file mode 100644
index 000000000000..627bc51d1b0f
--- /dev/null
+++ b/test/SemaCXX/warn-loop-analysis.cpp
@@ -0,0 +1,154 @@
+// RUN: %clang_cc1 -fsyntax-only -Wloop-analysis -verify %s
+
+struct S {
+ bool stop() { return false; }
+ bool keep_running;
+};
+
+void by_ref(int &value) { }
+void by_value(int value) { }
+void by_pointer(int *value) {}
+
+void test1() {
+ S s;
+ for (; !s.stop();) {}
+ for (; s.keep_running;) {}
+ for (int i; i < 1; ++i) {}
+ for (int i; i < 1; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (int i; i < 1; ) { ++i; }
+ for (int i; i < 1; ) { return; }
+ for (int i; i < 1; ) { break; }
+ for (int i; i < 1; ) { goto exit_loop; }
+exit_loop:
+ for (int i; i < 1; ) { by_ref(i); }
+ for (int i; i < 1; ) { by_value(i); } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (int i; i < 1; ) { by_pointer(&i); }
+
+ for (int i; i < 1; ++i)
+ for (int j; j < 1; ++j)
+ { }
+ for (int i; i < 1; ++i)
+ for (int j; j < 1; ++i) // expected-warning {{variable 'j' used in loop condition not modified in loop body}}
+ { }
+ for (int i; i < 1; ++i)
+ for (int j; i < 1; ++j) // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ { }
+
+ for (int *i, *j; i < j; ++i) {}
+ for (int *i, *j; i < j;) {} // expected-warning {{variables 'i' and 'j' used in loop condition not modified in loop body}}
+
+ // Dereferencing pointers is ignored for now.
+ for (int *i; *i; ) {}
+}
+
+void test2() {
+ int i, j, k;
+ int *ptr;
+
+ // Testing CastExpr
+ for (; i; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; i; ) { i = 5; }
+
+ // Testing BinaryOperator
+ for (; i < j; ) {} // expected-warning {{variables 'i' and 'j' used in loop condition not modified in loop body}}
+ for (; i < j; ) { i = 5; }
+ for (; i < j; ) { j = 5; }
+
+ // Testing IntegerLiteral
+ for (; i < 5; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; i < 5; ) { i = 5; }
+
+ // Testing FloatingLiteral
+ for (; i < 5.0; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; i < 5.0; ) { i = 5; }
+
+ // Testing CharacterLiteral
+ for (; i == 'a'; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; i == 'a'; ) { i = 5; }
+
+ // Testing CXXBoolLiteralExpr
+ for (; i == true; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; i == true; ) { i = 5; }
+
+ // Testing GNUNullExpr
+ for (; ptr == __null; ) {} // expected-warning {{variable 'ptr' used in loop condition not modified in loop body}}
+ for (; ptr == __null; ) { ptr = &i; }
+
+ // Testing UnaryOperator
+ for (; -i > 5; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; -i > 5; ) { ++i; }
+
+ // Testing ImaginaryLiteral
+ for (; i != 3i; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; i != 3i; ) { ++i; }
+
+ // Testing ConditionalOperator
+ for (; i ? j : k; ) {} // expected-warning {{variables 'i', 'j', and 'k' used in loop condition not modified in loop body}}
+ for (; i ? j : k; ) { ++i; }
+ for (; i ? j : k; ) { ++j; }
+ for (; i ? j : k; ) { ++k; }
+ for (; i; ) { j = i ? i : i; } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; i; ) { j = (i = 1) ? i : i; }
+ for (; i; ) { j = i ? i : ++i; }
+
+ // Testing BinaryConditionalOperator
+ for (; i ?: j; ) {} // expected-warning {{variables 'i' and 'j' used in loop condition not modified in loop body}}
+ for (; i ?: j; ) { ++i; }
+ for (; i ?: j; ) { ++j; }
+ for (; i; ) { j = i ?: i; } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+
+ // Testing ParenExpr
+ for (; (i); ) { } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; (i); ) { ++i; }
+
+ // Testing non-evaluated variables
+ for (; i < sizeof(j); ) { } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; i < sizeof(j); ) { ++j; } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
+ for (; i < sizeof(j); ) { ++i; }
+}
+
+// False positive and how to silence.
+void test3() {
+ int x;
+ int *ptr = &x;
+ for (;x<5;) { *ptr = 6; } // expected-warning {{variable 'x' used in loop condition not modified in loop body}}
+
+ for (;x<5;) {
+ *ptr = 6;
+ (void)x;
+ }
+}
+
+// Check ordering and printing of variables. Max variables is currently 4.
+void test4() {
+ int a, b, c, d, e, f;
+ for (; a;); // expected-warning {{variable 'a' used in loop condition not modified in loop body}}
+ for (; a + b;); // expected-warning {{variables 'a' and 'b' used in loop condition not modified in loop body}}
+ for (; a + b + c;); // expected-warning {{variables 'a', 'b', and 'c' used in loop condition not modified in loop body}}
+ for (; a + b + c + d;); // expected-warning {{variables 'a', 'b', 'c', and 'd' used in loop condition not modified in loop body}}
+ for (; a + b + c + d + e;); // expected-warning {{variables used in loop condition not modified in loop body}}
+ for (; a + b + c + d + e + f;); // expected-warning {{variables used in loop condition not modified in loop body}}
+ for (; a + c + d + b;); // expected-warning {{variables 'a', 'c', 'd', and 'b' used in loop condition not modified in loop body}}
+ for (; d + c + b + a;); // expected-warning {{variables 'd', 'c', 'b', and 'a' used in loop condition not modified in loop body}}
+}
+
+// Ensure that the warning doesn't fail when lots of variables are used
+// in the conditional.
+void test5() {
+ for (int a; a+a+a+a+a+a+a+a+a+a;); // \
+ // expected-warning {{variable 'a' used in loop condition not modified in loop body}}
+ for (int a; a+a+a+a+a+a+a+a+a+a+a;); // \
+ // expected-warning {{variable 'a' used in loop condition not modified in loop body}}
+ for (int a; a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a;); // \
+ // expected-warning {{variable 'a' used in loop condition not modified in loop body}}
+ for (int a; a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a+a;);//\
+ // expected-warning {{variable 'a' used in loop condition not modified in loop body}}
+}
+
+// Ignore global variables and static variables.
+int x6;
+void test6() {
+ static int y;
+ for (;x6;);
+ for (;y;);
+}
diff --git a/test/SemaCXX/warn-memset-bad-sizeof.cpp b/test/SemaCXX/warn-memset-bad-sizeof.cpp
index e0d28da3d589..e388634e8840 100644
--- a/test/SemaCXX/warn-memset-bad-sizeof.cpp
+++ b/test/SemaCXX/warn-memset-bad-sizeof.cpp
@@ -35,27 +35,27 @@ void f(Mat m, const Foo& const_foo, char *buffer) {
/* Should warn */
memset(&s, 0, sizeof(&s)); // \
- // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
+ // expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
memset(ps, 0, sizeof(ps)); // \
- // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
+ // expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
memset(ps2, 0, sizeof(ps2)); // \
- // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
+ // expected-warning {{'memset' call operates on objects of type 'S' while the size is based on a different type 'PS' (aka 'S *')}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
memset(ps2, 0, sizeof(typeof(ps2))); // \
// expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}
memset(ps2, 0, sizeof(PS)); // \
// expected-warning {{argument to 'sizeof' in 'memset' call is the same pointer type}}
memset(heap_buffer, 0, sizeof(heap_buffer)); // \
- // expected-warning {{argument to 'sizeof' in 'memset' call is the same expression as the destination}}
+ // expected-warning {{'memset' call operates on objects of type 'char' while the size is based on a different type 'char *'}} expected-note{{did you mean to provide an explicit length?}}
memcpy(&s, 0, sizeof(&s)); // \
- // expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the destination}}
+ // expected-warning {{'memcpy' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
memcpy(0, &s, sizeof(&s)); // \
- // expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the source}}
+ // expected-warning {{'memcpy' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to remove the addressof in the argument to 'sizeof' (and multiply it by the number of elements)?}}
memmove(ps, 0, sizeof(ps)); // \
- // expected-warning {{argument to 'sizeof' in 'memmove' call is the same expression as the destination}}
+ // expected-warning {{'memmove' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
memcmp(ps, 0, sizeof(ps)); // \
- // expected-warning {{argument to 'sizeof' in 'memcmp' call is the same expression as the destination}}
+ // expected-warning {{'memcmp' call operates on objects of type 'S' while the size is based on a different type 'S *'}} expected-note{{did you mean to dereference the argument to 'sizeof' (and multiply it by the number of elements)?}}
/* Shouldn't warn */
memset((void*)&s, 0, sizeof(&s));
@@ -132,14 +132,14 @@ void strcpy_and_friends() {
const char* BAR = "<- this, too";
strncmp(FOO, BAR, sizeof(FOO)); // \
- // expected-warning {{argument to 'sizeof' in 'strncmp' call is the same expression as the destination}}
+ // expected-warning {{'strncmp' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
strncasecmp(FOO, BAR, sizeof(FOO)); // \
- // expected-warning {{argument to 'sizeof' in 'strncasecmp' call is the same expression as the destination}}
+ // expected-warning {{'strncasecmp' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
char buff[80];
strncpy(buff, BAR, sizeof(BAR)); // \
- // expected-warning {{argument to 'sizeof' in 'strncpy' call is the same expression as the source}}
+ // expected-warning {{'strncpy' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
strndup(FOO, sizeof(FOO)); // \
- // expected-warning {{argument to 'sizeof' in 'strndup' call is the same expression as the source}}
+ // expected-warning {{'strndup' call operates on objects of type 'const char' while the size is based on a different type 'const char *'}} expected-note{{did you mean to provide an explicit length?}}
}
diff --git a/test/SemaCXX/warn-static-function-inheader.cpp b/test/SemaCXX/warn-static-function-inheader.cpp
new file mode 100644
index 000000000000..30386d9a258c
--- /dev/null
+++ b/test/SemaCXX/warn-static-function-inheader.cpp
@@ -0,0 +1,12 @@
+#include "warn-static-function-inheader.h"
+// RUN: %clang_cc1 -fsyntax-only -verify -Wall %s
+// rdar://11202617
+
+static void another(void) { // expected-warning {{function 'another' is not needed and will not be emitted}}
+}
+
+template <typename T>
+void foo(void) {
+ thing();
+ another();
+}
diff --git a/test/SemaCXX/warn-static-function-inheader.h b/test/SemaCXX/warn-static-function-inheader.h
new file mode 100644
index 000000000000..1c9e00b8bd22
--- /dev/null
+++ b/test/SemaCXX/warn-static-function-inheader.h
@@ -0,0 +1,3 @@
+static void thing(void) { // expected-warning {{'static' function 'thing' declared in header file should be declared 'static inline'}}
+}
+
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index 566e5c1b843b..17a1931c1594 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -1,4 +1,7 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 %s
+
+// FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
+// FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
#define LOCKABLE __attribute__ ((lockable))
#define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))
@@ -48,6 +51,30 @@ class __attribute__((scoped_lockable)) ReaderMutexLock {
~ReaderMutexLock() __attribute__((unlock_function));
};
+class SCOPED_LOCKABLE ReleasableMutexLock {
+ public:
+ ReleasableMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
+ ~ReleasableMutexLock() UNLOCK_FUNCTION();
+
+ void Release() UNLOCK_FUNCTION();
+};
+
+
+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_;
+};
+
Mutex sls_mu;
@@ -177,14 +204,11 @@ void sls_fun_bad_3() {
void sls_fun_bad_4() {
if (getBool())
- sls_mu.Lock(); // \
- expected-warning{{mutex 'sls_mu2' is not locked on every path through here}} \
- expected-note{{mutex acquired here}}
-
+ 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}}
+ 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}}
@@ -225,15 +249,14 @@ void sls_fun_bad_7() {
void sls_fun_bad_8() {
sls_mu.Lock(); // expected-note{{mutex acquired here}}
- // FIXME: TERRIBLE SOURCE LOCATION!
- do { // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
- sls_mu.Unlock();
+ 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(); // \
+ sls_mu.Lock(); // \
// expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
// expected-note{{mutex acquired here}}
} while (getBool());
@@ -241,15 +264,15 @@ void sls_fun_bad_9() {
}
void sls_fun_bad_10() {
- sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
- while(getBool()) {
- sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ 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}}
+ 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(); // \
@@ -506,7 +529,7 @@ void late_bad_0() {
LateFoo fooB;
fooA.mu.Lock();
fooB.a = 5; // \
- // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}}
fooA.mu.Unlock();
}
@@ -516,7 +539,7 @@ void late_bad_1() {
b1.mu1_.Lock();
int res = b1.a_ + b3->b_;
b3->b_ = *b1.q; // \
- // expected-warning{{reading the value pointed to by 'q' requires locking 'mu'}}
+ // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}}
b1.mu1_.Unlock();
b1.b_ = res;
mu.Unlock();
@@ -526,7 +549,7 @@ void late_bad_2() {
LateBar BarA;
BarA.FooPointer->mu.Lock();
BarA.Foo.a = 2; // \
- // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}}
BarA.FooPointer->mu.Unlock();
}
@@ -534,7 +557,7 @@ void late_bad_3() {
LateBar BarA;
BarA.Foo.mu.Lock();
BarA.FooPointer->a = 2; // \
- // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}}
BarA.Foo.mu.Unlock();
}
@@ -542,7 +565,7 @@ void late_bad_4() {
LateBar BarA;
BarA.Foo.mu.Lock();
BarA.Foo2.a = 2; // \
- // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}}
BarA.Foo.mu.Unlock();
}
@@ -1176,13 +1199,13 @@ void main()
{
Foo f1, *f2;
f1.mu_.Lock();
- f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
+ f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}}
mu2.Lock();
f1.foo();
mu2.Unlock();
f1.mu_.Unlock();
f2->mu_.Lock();
- f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
+ f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}}
f2->mu_.Unlock();
mu2.Lock();
w = 2;
@@ -1210,7 +1233,7 @@ void func()
{
b1->MyLock();
b1->a_ = 5;
- b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
+ b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}}
b2->MyLock();
b2->MyUnlock();
b1->MyUnlock();
@@ -1239,12 +1262,12 @@ int func(int i)
{
int x;
b3->mu1_.Lock();
- res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'mu1_'}} \
+ res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \
// expected-warning {{writing variable 'res' requires locking 'mu' exclusively}}
*p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
// expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
- // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
+ // expected-warning {{writing variable 'a_' requires locking 'b1.mu1_' exclusively}}
b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
b3->mu1_.Unlock();
b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
@@ -1269,8 +1292,8 @@ class Foo {
child->Func(new_foo); // There shouldn't be any warning here as the
// acquired lock is not in child.
- child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'lock_'}}
- child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'lock_' exclusively}}
+ child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'child->lock_'}}
+ child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}}
lock_.Unlock();
}
@@ -1307,7 +1330,7 @@ void Foo::Func(Foo* child) {
lock_.Lock();
child->lock_.Lock();
- child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'lock_' is locked}}
+ child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}}
child->bar(7);
child->a_ = 5;
child->lock_.Unlock();
@@ -1355,8 +1378,8 @@ Foo *foo;
void func()
{
- foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'mu2'}} \
- // expected-warning {{calling function 'f1' requires exclusive lock on 'mu1'}}
+ foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \
+ // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}}
}
} // end namespace thread_annot_lock_42
@@ -1379,14 +1402,14 @@ void main() {
Child *c;
Base *b = c;
- b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
+ b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}}
b->mu_.Lock();
- b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
+ b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}}
b->mu_.Unlock();
- c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
+ c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}}
c->mu_.Lock();
- c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
+ c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}}
c->mu_.Unlock();
}
} // end namespace thread_annot_lock_46
@@ -1413,9 +1436,9 @@ int Foo::method1(int i) {
void main()
{
Foo a;
- a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'mu1'}} \
+ a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \
// expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
- // expected-warning {{calling function 'method1' requires shared lock on 'mu2'}} \
+ // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \
// expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
}
} // end namespace thread_annot_lock_67_modified
@@ -1461,14 +1484,14 @@ namespace substitution_test {
DataLocker dlr;
dlr.lockData(d1); // expected-note {{mutex acquired here}}
dlr.unlockData(d2); // \
- // expected-warning {{unlocking 'mu' that was not locked}}
- } // expected-warning {{mutex 'mu' is still locked at the end of function}}
+ // expected-warning {{unlocking 'd2->mu' that was not locked}}
+ } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}}
void bar4(MyData* d1, MyData* d2) {
DataLocker dlr;
dlr.lockData(d1);
foo(d2); // \
- // expected-warning {{calling function 'foo' requires exclusive lock on 'mu'}}
+ // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}}
dlr.unlockData(d1);
}
};
@@ -1527,7 +1550,7 @@ namespace template_member_test {
struct IndirectLock {
int DoNaughtyThings(T *t) {
u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
- return t->s->n; // expected-warning {{reading variable 's' requires locking 'm'}}
+ return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}}
}
};
@@ -1543,7 +1566,7 @@ namespace template_member_test {
template<typename U> struct W {
V v;
void f(U u) {
- v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'm'}}
+ v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}}
}
};
template struct W<int>; // expected-note {{here}}
@@ -1581,7 +1604,7 @@ struct TestScopedLockable {
MutexLock mulock_a(&mu1);
MutexLock mulock_b(&mu1); // \
// expected-warning {{locking 'mu1' that is already locked}}
- } // expected-warning {{unlocking 'mu1' that was not locked}}
+ }
void foo4() {
MutexLock mulock1(&mu1), mulock2(&mu2);
@@ -1606,7 +1629,7 @@ Foo fooObj;
void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
void bar() {
- foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
+ foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}}
fooObj.mu_.Lock();
foo();
fooObj.mu_.Unlock();
@@ -1679,7 +1702,7 @@ struct TestTryLock {
bool b2 = b;
if (cond)
b = true;
- if (b) { // b should be unknown at this point, becuase of the join point
+ if (b) { // b should be unknown at this point, because of the join point
a = 8; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
}
if (b2) { // b2 should be known at this point.
@@ -1806,7 +1829,7 @@ void test() {
f1.mu_.Unlock();
bt.barTD(&f1); // \
- // expected-warning {{calling function 'barTD' requires exclusive lock on 'mu_'}}
+ // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}}
bt.fooBase.mu_.Unlock();
bt.fooBaseT.mu_.Unlock();
@@ -1814,7 +1837,7 @@ void test() {
Cell<int> cell;
cell.data = 0; // \
- // expected-warning {{writing variable 'data' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}}
cell.foo();
cell.mu_.Lock();
cell.fooEx();
@@ -1883,7 +1906,7 @@ void Foo::foo1(Foo *f_defined) {
void test() {
Foo myfoo;
myfoo.foo1(&myfoo); // \
- // expected-warning {{calling function 'foo1' requires exclusive lock on 'mu_'}}
+ // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}}
myfoo.mu_.Lock();
myfoo.foo1(&myfoo);
myfoo.mu_.Unlock();
@@ -1998,29 +2021,28 @@ void test() {
Foo myFoo;
myFoo.foo2(); // \
- // expected-warning {{calling function 'foo2' requires exclusive lock on 'mu_'}}
+ // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}}
myFoo.foo3(&myFoo); // \
- // expected-warning {{calling function 'foo3' requires exclusive lock on 'mu_'}}
+ // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}}
myFoo.fooT1(dummy); // \
- // expected-warning {{calling function 'fooT1' requires exclusive lock on 'mu_'}}
+ // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}}
- // FIXME: uncomment with template instantiation of attributes patch
- // myFoo.fooT2(dummy); // expected warning
+ myFoo.fooT2(dummy); // \
+ // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}}
fooF1(&myFoo); // \
- // expected-warning {{calling function 'fooF1' requires exclusive lock on 'mu_'}}
+ // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}}
fooF2(&myFoo); // \
- // expected-warning {{calling function 'fooF2' requires exclusive lock on 'mu_'}}
+ // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}}
fooF3(&myFoo); // \
- // expected-warning {{calling function 'fooF3' requires exclusive lock on 'mu_'}}
+ // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}}
myFoo.mu_.Lock();
myFoo.foo2();
myFoo.foo3(&myFoo);
myFoo.fooT1(dummy);
- // FIXME: uncomment with template instantiation of attributes patch
- // myFoo.fooT2(dummy);
+ myFoo.fooT2(dummy);
fooF1(&myFoo);
fooF2(&myFoo);
@@ -2029,7 +2051,7 @@ void test() {
FooT<int> myFooT;
myFooT.foo(); // \
- // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
+ // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}}
}
} // end namespace FunctionDefinitionTest
@@ -2213,31 +2235,887 @@ void test() {
bar.getFoo().mu_.Lock();
bar.getFooey().a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}}
bar.getFoo().mu_.Unlock();
bar.getFoo2(a).mu_.Lock();
bar.getFoo2(b).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}}
bar.getFoo2(a).mu_.Unlock();
bar.getFoo3(a, b).mu_.Lock();
bar.getFoo3(a, c).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}}
bar.getFoo3(a, b).mu_.Unlock();
getBarFoo(bar, a).mu_.Lock();
getBarFoo(bar, b).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}}
getBarFoo(bar, a).mu_.Unlock();
(a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
(a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}}
(a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
}
-} // end namespace
+} // end namespace MoreLockExpressions
+
+
+namespace TrylockJoinPoint {
+
+class Foo {
+ Mutex mu;
+ bool c;
+
+ void foo() {
+ if (c) {
+ if (!mu.TryLock())
+ return;
+ } else {
+ mu.Lock();
+ }
+ mu.Unlock();
+ }
+};
+
+} // end namespace TrylockJoinPoint
+
+
+namespace LockReturned {
+
+class Foo {
+public:
+ int a GUARDED_BY(mu_);
+ void foo() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+ void foo2(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(mu_, f->mu_);
+
+ static void sfoo(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_);
+
+ Mutex* getMu() LOCK_RETURNED(mu_);
+
+ Mutex mu_;
+
+ static Mutex* getMu(Foo* f) LOCK_RETURNED(f->mu_);
+};
+
+
+// Calls getMu() directly to lock and unlock
+void test1(Foo* f1, Foo* f2) {
+ f1->a = 0; // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}}
+ f1->foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}}
+
+ f1->foo2(f2); // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \
+ // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
+ Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}}
+
+ f1->getMu()->Lock();
+
+ f1->a = 0;
+ f1->foo();
+ f1->foo2(f2); // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
+
+ Foo::getMu(f2)->Lock();
+ f1->foo2(f2);
+ Foo::getMu(f2)->Unlock();
+
+ Foo::sfoo(f1);
+
+ f1->getMu()->Unlock();
+}
+
+
+Mutex* getFooMu(Foo* f) LOCK_RETURNED(Foo::getMu(f));
+
+class Bar : public Foo {
+public:
+ int b GUARDED_BY(getMu());
+ void bar() EXCLUSIVE_LOCKS_REQUIRED(getMu());
+ void bar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getMu(this), g->getMu());
+
+ static void sbar(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(g->getMu());
+ static void sbar2(Bar* g) EXCLUSIVE_LOCKS_REQUIRED(getFooMu(g));
+};
+
+
+
+// Use getMu() within other attributes.
+// This requires at lest levels of substitution, more in the case of
+void test2(Bar* b1, Bar* b2) {
+ b1->b = 0; // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}}
+ b1->bar(); // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}}
+ b1->bar2(b2); // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \
+ // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
+ Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}}
+ Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}}
+
+ b1->getMu()->Lock();
+
+ b1->b = 0;
+ b1->bar();
+ b1->bar2(b2); // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
+
+ b2->getMu()->Lock();
+ b1->bar2(b2);
+
+ b2->getMu()->Unlock();
+
+ Bar::sbar(b1);
+ Bar::sbar2(b1);
+
+ b1->getMu()->Unlock();
+}
+
+
+// Sanity check -- lock the mutex directly, but use attributes that call getMu()
+// Also lock the mutex using getFooMu, which calls a lock_returned function.
+void test3(Bar* b1, Bar* b2) {
+ b1->mu_.Lock();
+ b1->b = 0;
+ b1->bar();
+
+ getFooMu(b2)->Lock();
+ b1->bar2(b2);
+ getFooMu(b2)->Unlock();
+
+ Bar::sbar(b1);
+ Bar::sbar2(b1);
+
+ b1->mu_.Unlock();
+}
+
+} // end namespace LockReturned
+
+
+namespace ReleasableScopedLock {
+
+class Foo {
+ Mutex mu_;
+ bool c;
+ int a GUARDED_BY(mu_);
+
+ void test1();
+ void test2();
+ void test3();
+ void test4();
+ void test5();
+};
+
+
+void Foo::test1() {
+ ReleasableMutexLock rlock(&mu_);
+ rlock.Release();
+}
+
+void Foo::test2() {
+ ReleasableMutexLock rlock(&mu_);
+ if (c) { // test join point -- held/not held during release
+ rlock.Release();
+ }
+}
+
+void Foo::test3() {
+ ReleasableMutexLock rlock(&mu_);
+ a = 0;
+ rlock.Release();
+ a = 1; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+}
+
+void Foo::test4() {
+ ReleasableMutexLock rlock(&mu_);
+ rlock.Release();
+ rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}}
+}
+
+void Foo::test5() {
+ ReleasableMutexLock rlock(&mu_);
+ if (c) {
+ rlock.Release();
+ }
+ // no warning on join point for managed lock.
+ rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}}
+}
+
+
+} // end namespace ReleasableScopedLock
+
+
+namespace TrylockFunctionTest {
+
+class Foo {
+public:
+ Mutex mu1_;
+ Mutex mu2_;
+ bool c;
+
+ bool lockBoth() EXCLUSIVE_TRYLOCK_FUNCTION(true, mu1_, mu2_);
+};
+
+bool Foo::lockBoth() {
+ if (!mu1_.TryLock())
+ return false;
+
+ mu2_.Lock();
+ if (!c) {
+ mu1_.Unlock();
+ mu2_.Unlock();
+ return false;
+ }
+
+ return true;
+}
+
+
+} // end namespace TrylockFunctionTest
+
+
+
+namespace DoubleLockBug {
+
+class Foo {
+public:
+ Mutex mu_;
+ int a GUARDED_BY(mu_);
+
+ void foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+ int foo2() SHARED_LOCKS_REQUIRED(mu_);
+};
+
+
+void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
+ a = 0;
+}
+
+int Foo::foo2() SHARED_LOCKS_REQUIRED(mu_) {
+ return a;
+}
+
+}
+
+
+
+namespace UnlockBug {
+
+class Foo {
+public:
+ Mutex mutex_;
+
+ void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
+ mutex_.Unlock();
+ } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
+
+
+ void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
+ mutex_.Unlock();
+ } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
+};
+
+} // end namespace UnlockBug
+
+
+
+namespace FoolishScopedLockableBug {
+
+class SCOPED_LOCKABLE WTF_ScopedLockable {
+public:
+ WTF_ScopedLockable(Mutex* mu) EXCLUSIVE_LOCK_FUNCTION(mu);
+
+ // have to call release() manually;
+ ~WTF_ScopedLockable();
+
+ void release() UNLOCK_FUNCTION();
+};
+
+
+class Foo {
+ Mutex mu_;
+ int a GUARDED_BY(mu_);
+ bool c;
+
+ void doSomething();
+
+ void test1() {
+ WTF_ScopedLockable wtf(&mu_);
+ wtf.release();
+ }
+
+ void test2() {
+ WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
+ } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+
+ void test3() {
+ if (c) {
+ WTF_ScopedLockable wtf(&mu_);
+ wtf.release();
+ }
+ }
+
+ void test4() {
+ if (c) {
+ doSomething();
+ }
+ else {
+ WTF_ScopedLockable wtf(&mu_);
+ wtf.release();
+ }
+ }
+
+ void test5() {
+ if (c) {
+ WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
+ }
+ } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
+
+ void test6() {
+ if (c) {
+ doSomething();
+ }
+ else {
+ WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
+ }
+ } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
+};
+
+
+} // end namespace FoolishScopedLockableBug
+
+
+
+namespace TemporaryCleanupExpr {
+
+class Foo {
+ int a GUARDED_BY(getMutexPtr().get());
+
+ SmartPtr<Mutex> getMutexPtr();
+
+ void test();
+};
+
+
+void Foo::test() {
+ {
+ ReaderMutexLock lock(getMutexPtr().get());
+ int b = a;
+ }
+ int b = a; // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}}
+}
+
+} // end namespace TemporaryCleanupExpr
+
+
+
+namespace SmartPointerTests {
+
+class Foo {
+public:
+ SmartPtr<Mutex> mu_;
+ int a GUARDED_BY(mu_);
+ int b GUARDED_BY(mu_.get());
+ int c GUARDED_BY(*mu_);
+
+ void Lock() EXCLUSIVE_LOCK_FUNCTION(mu_);
+ void Unlock() UNLOCK_FUNCTION(mu_);
+
+ void test0();
+ void test1();
+ void test2();
+ void test3();
+ void test4();
+ void test5();
+ void test6();
+ void test7();
+ void test8();
+};
+
+void Foo::test0() {
+ a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ b = 0; // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
+ c = 0; // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
+}
+
+void Foo::test1() {
+ mu_->Lock();
+ a = 0;
+ b = 0;
+ c = 0;
+ mu_->Unlock();
+}
+
+void Foo::test2() {
+ (*mu_).Lock();
+ a = 0;
+ b = 0;
+ c = 0;
+ (*mu_).Unlock();
+}
+
+
+void Foo::test3() {
+ mu_.get()->Lock();
+ a = 0;
+ b = 0;
+ c = 0;
+ mu_.get()->Unlock();
+}
+
+
+void Foo::test4() {
+ MutexLock lock(mu_.get());
+ a = 0;
+ b = 0;
+ c = 0;
+}
+
+
+void Foo::test5() {
+ MutexLock lock(&(*mu_));
+ a = 0;
+ b = 0;
+ c = 0;
+}
+
+
+void Foo::test6() {
+ Lock();
+ a = 0;
+ b = 0;
+ c = 0;
+ Unlock();
+}
+
+
+void Foo::test7() {
+ {
+ Lock();
+ mu_->Unlock();
+ }
+ {
+ mu_->Lock();
+ Unlock();
+ }
+ {
+ mu_.get()->Lock();
+ mu_->Unlock();
+ }
+ {
+ mu_->Lock();
+ mu_.get()->Unlock();
+ }
+ {
+ mu_.get()->Lock();
+ (*mu_).Unlock();
+ }
+ {
+ (*mu_).Lock();
+ mu_->Unlock();
+ }
+}
+
+
+void Foo::test8() {
+ mu_->Lock();
+ mu_.get()->Lock(); // expected-warning {{locking 'mu_' that is already locked}}
+ (*mu_).Lock(); // expected-warning {{locking 'mu_' that is already locked}}
+ mu_.get()->Unlock();
+ Unlock(); // expected-warning {{unlocking 'mu_' that was not locked}}
+}
+
+
+class Bar {
+ SmartPtr<Foo> foo;
+
+ void test0();
+ void test1();
+ void test2();
+ void test3();
+};
+
+
+void Bar::test0() {
+ foo->a = 0; // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}}
+ (*foo).b = 0; // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}}
+ foo.get()->c = 0; // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}}
+}
+
+
+void Bar::test1() {
+ foo->mu_->Lock();
+ foo->a = 0;
+ (*foo).b = 0;
+ foo.get()->c = 0;
+ foo->mu_->Unlock();
+}
+
+
+void Bar::test2() {
+ (*foo).mu_->Lock();
+ foo->a = 0;
+ (*foo).b = 0;
+ foo.get()->c = 0;
+ foo.get()->mu_->Unlock();
+}
+
+
+void Bar::test3() {
+ MutexLock lock(foo->mu_.get());
+ foo->a = 0;
+ (*foo).b = 0;
+ foo.get()->c = 0;
+}
+
+} // end namespace SmartPointerTests
+
+
+
+namespace DuplicateAttributeTest {
+
+class LOCKABLE Foo {
+public:
+ Mutex mu1_;
+ Mutex mu2_;
+ Mutex mu3_;
+ int a GUARDED_BY(mu1_);
+ int b GUARDED_BY(mu2_);
+ int c GUARDED_BY(mu3_);
+
+ void lock() EXCLUSIVE_LOCK_FUNCTION();
+ void unlock() UNLOCK_FUNCTION();
+
+ void lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_);
+ void slock1() SHARED_LOCK_FUNCTION(mu1_);
+ void lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
+ void locklots()
+ EXCLUSIVE_LOCK_FUNCTION(mu1_)
+ EXCLUSIVE_LOCK_FUNCTION(mu2_)
+ EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_);
+
+ void unlock1() UNLOCK_FUNCTION(mu1_);
+ void unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
+ void unlocklots()
+ UNLOCK_FUNCTION(mu1_)
+ UNLOCK_FUNCTION(mu2_)
+ UNLOCK_FUNCTION(mu1_, mu2_, mu3_);
+};
+
+
+void Foo::lock() EXCLUSIVE_LOCK_FUNCTION() { }
+void Foo::unlock() UNLOCK_FUNCTION() { }
+
+void Foo::lock1() EXCLUSIVE_LOCK_FUNCTION(mu1_) {
+ mu1_.Lock();
+}
+
+void Foo::slock1() SHARED_LOCK_FUNCTION(mu1_) {
+ mu1_.Lock();
+}
+
+void Foo::lock3() EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_, mu3_) {
+ mu1_.Lock();
+ mu2_.Lock();
+ mu3_.Lock();
+}
+
+void Foo::locklots()
+ EXCLUSIVE_LOCK_FUNCTION(mu1_, mu2_)
+ EXCLUSIVE_LOCK_FUNCTION(mu2_, mu3_) {
+ mu1_.Lock();
+ mu2_.Lock();
+ mu3_.Lock();
+}
+
+void Foo::unlock1() UNLOCK_FUNCTION(mu1_) {
+ mu1_.Unlock();
+}
+
+void Foo::unlock3() UNLOCK_FUNCTION(mu1_, mu2_, mu3_) {
+ mu1_.Unlock();
+ mu2_.Unlock();
+ mu3_.Unlock();
+}
+
+void Foo::unlocklots()
+ UNLOCK_FUNCTION(mu1_, mu2_)
+ UNLOCK_FUNCTION(mu2_, mu3_) {
+ mu1_.Unlock();
+ mu2_.Unlock();
+ mu3_.Unlock();
+}
+
+
+void test0() {
+ Foo foo;
+ foo.lock();
+ foo.unlock();
+
+ foo.lock();
+ foo.lock(); // expected-warning {{locking 'foo' that is already locked}}
+ foo.unlock();
+ foo.unlock(); // expected-warning {{unlocking 'foo' that was not locked}}
+}
+
+
+void test1() {
+ Foo foo;
+ foo.lock1();
+ foo.a = 0;
+ foo.unlock1();
+
+ foo.lock1();
+ foo.lock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}}
+ foo.a = 0;
+ foo.unlock1();
+ foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
+}
+
+
+int test2() {
+ Foo foo;
+ foo.slock1();
+ int d1 = foo.a;
+ foo.unlock1();
+
+ foo.slock1();
+ foo.slock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}}
+ int d2 = foo.a;
+ foo.unlock1();
+ foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
+ return d1 + d2;
+}
+
+
+void test3() {
+ Foo foo;
+ foo.lock3();
+ foo.a = 0;
+ foo.b = 0;
+ foo.c = 0;
+ foo.unlock3();
+
+ foo.lock3();
+ foo.lock3(); // \
+ // expected-warning {{locking 'foo.mu1_' that is already locked}} \
+ // expected-warning {{locking 'foo.mu2_' that is already locked}} \
+ // expected-warning {{locking 'foo.mu3_' that is already locked}}
+ foo.a = 0;
+ foo.b = 0;
+ foo.c = 0;
+ foo.unlock3();
+ foo.unlock3(); // \
+ // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
+ // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
+ // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
+}
+
+
+void testlots() {
+ Foo foo;
+ foo.locklots();
+ foo.a = 0;
+ foo.b = 0;
+ foo.c = 0;
+ foo.unlocklots();
+
+ foo.locklots();
+ foo.locklots(); // \
+ // expected-warning {{locking 'foo.mu1_' that is already locked}} \
+ // expected-warning {{locking 'foo.mu2_' that is already locked}} \
+ // expected-warning {{locking 'foo.mu3_' that is already locked}}
+ foo.a = 0;
+ foo.b = 0;
+ foo.c = 0;
+ foo.unlocklots();
+ foo.unlocklots(); // \
+ // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
+ // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
+ // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
+}
+
+} // end namespace DuplicateAttributeTest
+
+
+
+namespace TryLockEqTest {
+
+class Foo {
+ Mutex mu_;
+ int a GUARDED_BY(mu_);
+ bool c;
+
+ int tryLockMutexI() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
+ Mutex* tryLockMutexP() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu_);
+ void unlock() UNLOCK_FUNCTION(mu_);
+
+ void test1();
+ void test2();
+};
+
+
+void Foo::test1() {
+ if (tryLockMutexP() == 0) {
+ a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ return;
+ }
+ a = 0;
+ unlock();
+
+ if (tryLockMutexP() != 0) {
+ a = 0;
+ unlock();
+ }
+
+ if (0 != tryLockMutexP()) {
+ a = 0;
+ unlock();
+ }
+
+ if (!(tryLockMutexP() == 0)) {
+ a = 0;
+ unlock();
+ }
+
+ if (tryLockMutexI() == 0) {
+ a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ return;
+ }
+ a = 0;
+ unlock();
+
+ if (0 == tryLockMutexI()) {
+ a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ return;
+ }
+ a = 0;
+ unlock();
+
+ if (tryLockMutexI() == 1) {
+ a = 0;
+ unlock();
+ }
+
+ if (mu_.TryLock() == false) {
+ a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ return;
+ }
+ a = 0;
+ unlock();
+
+ if (mu_.TryLock() == true) {
+ a = 0;
+ unlock();
+ }
+ else {
+ a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ }
+
+#if __has_feature(cxx_nullptr)
+ if (tryLockMutexP() == nullptr) {
+ a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ return;
+ }
+ a = 0;
+ unlock();
+#endif
+}
+
+
+void Foo::test2() {
+/* FIXME: these tests depend on changes to the CFG.
+ *
+ if (mu_.TryLock() && c) {
+ a = 0;
+ unlock();
+ }
+ else return;
+
+ if (c && mu_.TryLock()) {
+ a = 0;
+ unlock();
+ }
+ else return;
+
+ if (!(mu_.TryLock() && c))
+ return;
+ a = 0;
+ unlock();
+
+ if (!(c && mu_.TryLock()))
+ return;
+ a = 0;
+ unlock();
+
+ if (!(mu_.TryLock() == 0) && c) {
+ a = 0;
+ unlock();
+ }
+
+ if (!mu_.TryLock() || c)
+ return;
+ a = 0;
+ unlock();
+*/
+}
+
+} // end namespace TryLockEqTest
+
+
+namespace ExistentialPatternMatching {
+
+class Graph {
+public:
+ Mutex mu_;
+};
+
+void LockAllGraphs() EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
+void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
+
+class Node {
+public:
+ int a GUARDED_BY(&Graph::mu_);
+
+ void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
+ a = 0;
+ }
+ void foo2() LOCKS_EXCLUDED(&Graph::mu_);
+};
+
+void test() {
+ Graph g1;
+ Graph g2;
+ Node n1;
+
+ n1.a = 0; // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}}
+ n1.foo(); // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}}
+ n1.foo2();
+
+ g1.mu_.Lock();
+ n1.a = 0;
+ n1.foo();
+ n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+ g1.mu_.Unlock();
+
+ g2.mu_.Lock();
+ n1.a = 0;
+ n1.foo();
+ n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+ g2.mu_.Unlock();
+
+ LockAllGraphs();
+ n1.a = 0;
+ n1.foo();
+ n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+ UnlockAllGraphs();
+
+ LockAllGraphs();
+ g1.mu_.Unlock();
+
+ LockAllGraphs();
+ g2.mu_.Unlock();
+
+ LockAllGraphs();
+ g1.mu_.Lock(); // expected-warning {{locking 'g1.mu_' that is already locked}}
+ g1.mu_.Unlock();
+}
+} // end namespace ExistentialPatternMatching
diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp
index c2fa1d77a01a..3f8a7359088d 100644
--- a/test/SemaCXX/warn-thread-safety-parsing.cpp
+++ b/test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -22,7 +22,7 @@
#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))
-class __attribute__((lockable)) Mu {
+class LOCKABLE Mutex {
public:
void Lock();
};
@@ -32,11 +32,11 @@ class UnlockableMu{
class MuWrapper {
public:
- Mu mu;
- Mu getMu() {
+ Mutex mu;
+ Mutex getMu() {
return mu;
}
- Mu * getMuPointer() {
+ Mutex * getMuPointer() {
return &mu;
}
};
@@ -50,32 +50,32 @@ class MuDoubleWrapper {
}
};
-Mu mu1;
+Mutex mu1;
UnlockableMu umu;
-Mu mu2;
+Mutex mu2;
MuWrapper muWrapper;
MuDoubleWrapper muDoubleWrapper;
-Mu* muPointer;
-Mu ** muDoublePointer = & muPointer;
-Mu& muRef = mu1;
+Mutex* muPointer;
+Mutex** muDoublePointer = & muPointer;
+Mutex& muRef = mu1;
//---------------------------------------//
// Scoping tests
//--------------------------------------//
class Foo {
- Mu foomu;
- void needLock() __attribute__((exclusive_lock_function(foomu)));
+ Mutex foomu;
+ void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu);
};
class Foo2 {
- void needLock() __attribute__((exclusive_lock_function(foomu)));
- Mu foomu;
+ void needLock() EXCLUSIVE_LOCK_FUNCTION(foomu);
+ Mutex foomu;
};
class Bar {
- Mu barmu;
- Mu barmu2 __attribute__((acquired_after(barmu)));
+ Mutex barmu;
+ Mutex barmu2 ACQUIRED_AFTER(barmu);
};
@@ -90,34 +90,34 @@ class Bar {
#error "Should support no_thread_safety_analysis attribute"
#endif
-void noanal_fun() __attribute__((no_thread_safety_analysis));
+void noanal_fun() NO_THREAD_SAFETY_ANALYSIS;
void noanal_fun_args() __attribute__((no_thread_safety_analysis(1))); // \
// expected-error {{attribute takes no arguments}}
-int noanal_testfn(int y) __attribute__((no_thread_safety_analysis));
+int noanal_testfn(int y) NO_THREAD_SAFETY_ANALYSIS;
int noanal_testfn(int y) {
- int x __attribute__((no_thread_safety_analysis)) = y; // \
+ int x NO_THREAD_SAFETY_ANALYSIS = y; // \
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
return x;
};
-int noanal_test_var __attribute__((no_thread_safety_analysis)); // \
+int noanal_test_var NO_THREAD_SAFETY_ANALYSIS; // \
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
class NoanalFoo {
private:
- int test_field __attribute__((no_thread_safety_analysis)); // \
+ int test_field NO_THREAD_SAFETY_ANALYSIS; // \
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
- void test_method() __attribute__((no_thread_safety_analysis));
+ void test_method() NO_THREAD_SAFETY_ANALYSIS;
};
-class __attribute__((no_thread_safety_analysis)) NoanalTestClass { // \
+class NO_THREAD_SAFETY_ANALYSIS NoanalTestClass { // \
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
};
-void noanal_fun_params(int lvar __attribute__((no_thread_safety_analysis))); // \
+void noanal_fun_params(int lvar NO_THREAD_SAFETY_ANALYSIS); // \
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
@@ -129,30 +129,30 @@ void noanal_fun_params(int lvar __attribute__((no_thread_safety_analysis))); //
#error "Should support guarded_var attribute"
#endif
-int gv_var_noargs __attribute__((guarded_var));
+int gv_var_noargs GUARDED_VAR;
int gv_var_args __attribute__((guarded_var(1))); // \
// expected-error {{attribute takes no arguments}}
class GVFoo {
private:
- int gv_field_noargs __attribute__((guarded_var));
+ int gv_field_noargs GUARDED_VAR;
int gv_field_args __attribute__((guarded_var(1))); // \
// expected-error {{attribute takes no arguments}}
};
-class __attribute__((guarded_var)) GV { // \
+class GUARDED_VAR GV { // \
// expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
};
-void gv_function() __attribute__((guarded_var)); // \
+void gv_function() GUARDED_VAR; // \
// expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
-void gv_function_params(int gv_lvar __attribute__((guarded_var))); // \
+void gv_function_params(int gv_lvar GUARDED_VAR); // \
// expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
int gv_testfn(int y){
- int x __attribute__((guarded_var)) = y; // \
+ int x GUARDED_VAR = y; // \
// expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
return x;
}
@@ -167,21 +167,21 @@ int gv_testfn(int y){
#error "Should support pt_guarded_var attribute"
#endif
-int *pgv_pt_var_noargs __attribute__((pt_guarded_var));
+int *pgv_pt_var_noargs PT_GUARDED_VAR;
-int pgv_var_noargs __attribute__((pt_guarded_var)); // \
+int pgv_var_noargs PT_GUARDED_VAR; // \
// expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
class PGVFoo {
private:
- int *pt_field_noargs __attribute__((pt_guarded_var));
- int field_noargs __attribute__((pt_guarded_var)); // \
+ int *pt_field_noargs PT_GUARDED_VAR;
+ int field_noargs PT_GUARDED_VAR; // \
// expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
int *gv_field_args __attribute__((pt_guarded_var(1))); // \
// expected-error {{attribute takes no arguments}}
};
-class __attribute__((pt_guarded_var)) PGV { // \
+class PT_GUARDED_VAR PGV { // \
// expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
};
@@ -189,14 +189,14 @@ int *pgv_var_args __attribute__((pt_guarded_var(1))); // \
// expected-error {{attribute takes no arguments}}
-void pgv_function() __attribute__((pt_guarded_var)); // \
+void pgv_function() PT_GUARDED_VAR; // \
// expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
-void pgv_function_params(int *gv_lvar __attribute__((pt_guarded_var))); // \
+void pgv_function_params(int *gv_lvar PT_GUARDED_VAR); // \
// expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
void pgv_testfn(int y){
- int *x __attribute__((pt_guarded_var)) = new int(0); // \
+ int *x PT_GUARDED_VAR = new int(0); // \
// expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
delete x;
}
@@ -211,35 +211,35 @@ void pgv_testfn(int y){
#error "Should support lockable attribute"
#endif
-class __attribute__((lockable)) LTestClass {
+class LOCKABLE LTestClass {
};
class __attribute__((lockable (1))) LTestClass_args { // \
// expected-error {{attribute takes no arguments}}
};
-void l_test_function() __attribute__((lockable)); // \
+void l_test_function() LOCKABLE; // \
// expected-warning {{'lockable' attribute only applies to classes}}
int l_testfn(int y) {
- int x __attribute__((lockable)) = y; // \
+ int x LOCKABLE = y; // \
// expected-warning {{'lockable' attribute only applies to classes}}
return x;
}
-int l_test_var __attribute__((lockable)); // \
+int l_test_var LOCKABLE; // \
// expected-warning {{'lockable' attribute only applies to classes}}
class LFoo {
private:
- int test_field __attribute__((lockable)); // \
+ int test_field LOCKABLE; // \
// expected-warning {{'lockable' attribute only applies to classes}}
- void test_method() __attribute__((lockable)); // \
+ void test_method() LOCKABLE; // \
// expected-warning {{'lockable' attribute only applies to classes}}
};
-void l_function_params(int lvar __attribute__((lockable))); // \
+void l_function_params(int lvar LOCKABLE); // \
// expected-warning {{'lockable' attribute only applies to classes}}
@@ -251,35 +251,35 @@ void l_function_params(int lvar __attribute__((lockable))); // \
#error "Should support scoped_lockable attribute"
#endif
-class __attribute__((scoped_lockable)) SLTestClass {
+class SCOPED_LOCKABLE SLTestClass {
};
class __attribute__((scoped_lockable (1))) SLTestClass_args { // \
// expected-error {{attribute takes no arguments}}
};
-void sl_test_function() __attribute__((scoped_lockable)); // \
+void sl_test_function() SCOPED_LOCKABLE; // \
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
int sl_testfn(int y) {
- int x __attribute__((scoped_lockable)) = y; // \
+ int x SCOPED_LOCKABLE = y; // \
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
return x;
}
-int sl_test_var __attribute__((scoped_lockable)); // \
+int sl_test_var SCOPED_LOCKABLE; // \
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
class SLFoo {
private:
- int test_field __attribute__((scoped_lockable)); // \
+ int test_field SCOPED_LOCKABLE; // \
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
- void test_method() __attribute__((scoped_lockable)); // \
+ void test_method() SCOPED_LOCKABLE; // \
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
};
-void sl_function_params(int lvar __attribute__((scoped_lockable))); // \
+void sl_function_params(int lvar SCOPED_LOCKABLE); // \
// expected-warning {{'scoped_lockable' attribute only applies to classes}}
@@ -295,7 +295,7 @@ void sl_function_params(int lvar __attribute__((scoped_lockable))); // \
//1. Check applied to the right types & argument number
-int gb_var_arg __attribute__((guarded_by(mu1)));
+int gb_var_arg GUARDED_BY(mu1);
int gb_var_args __attribute__((guarded_by(mu1, mu2))); // \
// expected-error {{attribute takes one argument}}
@@ -307,21 +307,21 @@ class GBFoo {
private:
int gb_field_noargs __attribute__((guarded_by)); // \
// expected-error {{attribute takes one argument}}
- int gb_field_args __attribute__((guarded_by(mu1)));
+ int gb_field_args GUARDED_BY(mu1);
};
-class __attribute__((guarded_by(mu1))) GB { // \
+class GUARDED_BY(mu1) GB { // \
// expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
};
-void gb_function() __attribute__((guarded_by(mu1))); // \
+void gb_function() GUARDED_BY(mu1); // \
// expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
-void gb_function_params(int gv_lvar __attribute__((guarded_by(mu1)))); // \
+void gb_function_params(int gv_lvar GUARDED_BY(mu1)); // \
// expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
int gb_testfn(int y){
- int x __attribute__((guarded_by(mu1))) = y; // \
+ int x GUARDED_BY(mu1) = y; // \
// expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
return x;
}
@@ -329,24 +329,24 @@ int gb_testfn(int y){
//2. Check argument parsing.
// legal attribute arguments
-int gb_var_arg_1 __attribute__((guarded_by(muWrapper.mu)));
-int gb_var_arg_2 __attribute__((guarded_by(muDoubleWrapper.muWrapper->mu)));
-int gb_var_arg_3 __attribute__((guarded_by(muWrapper.getMu())));
-int gb_var_arg_4 __attribute__((guarded_by(*muWrapper.getMuPointer())));
-int gb_var_arg_5 __attribute__((guarded_by(&mu1)));
-int gb_var_arg_6 __attribute__((guarded_by(muRef)));
-int gb_var_arg_7 __attribute__((guarded_by(muDoubleWrapper.getWrapper()->getMu())));
-int gb_var_arg_8 __attribute__((guarded_by(muPointer)));
+int gb_var_arg_1 GUARDED_BY(muWrapper.mu);
+int gb_var_arg_2 GUARDED_BY(muDoubleWrapper.muWrapper->mu);
+int gb_var_arg_3 GUARDED_BY(muWrapper.getMu());
+int gb_var_arg_4 GUARDED_BY(*muWrapper.getMuPointer());
+int gb_var_arg_5 GUARDED_BY(&mu1);
+int gb_var_arg_6 GUARDED_BY(muRef);
+int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());
+int gb_var_arg_8 GUARDED_BY(muPointer);
// illegal attribute arguments
-int gb_var_arg_bad_1 __attribute__((guarded_by(1))); // \
+int gb_var_arg_bad_1 GUARDED_BY(1); // \
// expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'int'}}
-int gb_var_arg_bad_2 __attribute__((guarded_by("mu"))); // \
- // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'const char [3]'}}
-int gb_var_arg_bad_3 __attribute__((guarded_by(muDoublePointer))); // \
- // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'class Mu **'}}
-int gb_var_arg_bad_4 __attribute__((guarded_by(umu))); // \
+int gb_var_arg_bad_2 GUARDED_BY("mu"); // \
+ // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
+int gb_var_arg_bad_3 GUARDED_BY(muDoublePointer); // \
+ // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'class Mutex **'}}
+int gb_var_arg_bad_4 GUARDED_BY(umu); // \
// expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class UnlockableMu'}}
//3.
@@ -366,33 +366,33 @@ int gb_var_arg_bad_4 __attribute__((guarded_by(umu))); // \
int *pgb_var_noargs __attribute__((pt_guarded_by)); // \
// expected-error {{attribute takes one argument}}
-int *pgb_ptr_var_arg __attribute__((pt_guarded_by(mu1)));
+int *pgb_ptr_var_arg PT_GUARDED_BY(mu1);
-int *pgb_ptr_var_args __attribute__((guarded_by(mu1, mu2))); // \
+int *pgb_ptr_var_args __attribute__((pt_guarded_by(mu1, mu2))); // \
// expected-error {{attribute takes one argument}}
-int pgb_var_args __attribute__((pt_guarded_by(mu1))); // \
+int pgb_var_args PT_GUARDED_BY(mu1); // \
// expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
class PGBFoo {
private:
int *pgb_field_noargs __attribute__((pt_guarded_by)); // \
// expected-error {{attribute takes one argument}}
- int *pgb_field_args __attribute__((pt_guarded_by(mu1)));
+ int *pgb_field_args PT_GUARDED_BY(mu1);
};
-class __attribute__((pt_guarded_by(mu1))) PGB { // \
+class PT_GUARDED_BY(mu1) PGB { // \
// expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
};
-void pgb_function() __attribute__((pt_guarded_by(mu1))); // \
+void pgb_function() PT_GUARDED_BY(mu1); // \
// expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
-void pgb_function_params(int gv_lvar __attribute__((pt_guarded_by(mu1)))); // \
+void pgb_function_params(int gv_lvar PT_GUARDED_BY(mu1)); // \
// expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
void pgb_testfn(int y){
- int *x __attribute__((pt_guarded_by(mu1))) = new int(0); // \
+ int *x PT_GUARDED_BY(mu1) = new int(0); // \
// expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
delete x;
}
@@ -400,24 +400,24 @@ void pgb_testfn(int y){
//2. Check argument parsing.
// legal attribute arguments
-int * pgb_var_arg_1 __attribute__((pt_guarded_by(muWrapper.mu)));
-int * pgb_var_arg_2 __attribute__((pt_guarded_by(muDoubleWrapper.muWrapper->mu)));
-int * pgb_var_arg_3 __attribute__((pt_guarded_by(muWrapper.getMu())));
-int * pgb_var_arg_4 __attribute__((pt_guarded_by(*muWrapper.getMuPointer())));
-int * pgb_var_arg_5 __attribute__((pt_guarded_by(&mu1)));
-int * pgb_var_arg_6 __attribute__((pt_guarded_by(muRef)));
-int * pgb_var_arg_7 __attribute__((pt_guarded_by(muDoubleWrapper.getWrapper()->getMu())));
-int * pgb_var_arg_8 __attribute__((pt_guarded_by(muPointer)));
+int * pgb_var_arg_1 PT_GUARDED_BY(muWrapper.mu);
+int * pgb_var_arg_2 PT_GUARDED_BY(muDoubleWrapper.muWrapper->mu);
+int * pgb_var_arg_3 PT_GUARDED_BY(muWrapper.getMu());
+int * pgb_var_arg_4 PT_GUARDED_BY(*muWrapper.getMuPointer());
+int * pgb_var_arg_5 PT_GUARDED_BY(&mu1);
+int * pgb_var_arg_6 PT_GUARDED_BY(muRef);
+int * pgb_var_arg_7 PT_GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());
+int * pgb_var_arg_8 PT_GUARDED_BY(muPointer);
// illegal attribute arguments
-int * pgb_var_arg_bad_1 __attribute__((pt_guarded_by(1))); // \
+int * pgb_var_arg_bad_1 PT_GUARDED_BY(1); // \
// expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
-int * pgb_var_arg_bad_2 __attribute__((pt_guarded_by("mu"))); // \
+int * pgb_var_arg_bad_2 PT_GUARDED_BY("mu"); // \
+ // expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}}
+int * pgb_var_arg_bad_3 PT_GUARDED_BY(muDoublePointer); // \
// expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
-int * pgb_var_arg_bad_3 __attribute__((pt_guarded_by(muDoublePointer))); // \
- // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
-int * pgb_var_arg_bad_4 __attribute__((pt_guarded_by(umu))); // \
+int * pgb_var_arg_bad_4 PT_GUARDED_BY(umu); // \
// expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute}}
@@ -431,56 +431,56 @@ int * pgb_var_arg_bad_4 __attribute__((pt_guarded_by(umu))); // \
#error "Should support acquired_after attribute"
#endif
-Mu mu_aa __attribute__((acquired_after(mu1)));
+Mutex mu_aa ACQUIRED_AFTER(mu1);
-Mu aa_var_noargs __attribute__((acquired_after)); // \
+Mutex aa_var_noargs __attribute__((acquired_after)); // \
// expected-error {{attribute takes at least 1 argument}}
class AAFoo {
private:
- Mu aa_field_noargs __attribute__((acquired_after)); // \
+ Mutex aa_field_noargs __attribute__((acquired_after)); // \
// expected-error {{attribute takes at least 1 argument}}
- Mu aa_field_args __attribute__((acquired_after(mu1)));
+ Mutex aa_field_args ACQUIRED_AFTER(mu1);
};
-class __attribute__((acquired_after(mu1))) AA { // \
+class ACQUIRED_AFTER(mu1) AA { // \
// expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
};
-void aa_function() __attribute__((acquired_after(mu1))); // \
+void aa_function() ACQUIRED_AFTER(mu1); // \
// expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
-void aa_function_params(int gv_lvar __attribute__((acquired_after(mu1)))); // \
+void aa_function_params(int gv_lvar ACQUIRED_AFTER(mu1)); // \
// expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
void aa_testfn(int y){
- Mu x __attribute__((acquired_after(mu1))) = Mu(); // \
+ Mutex x ACQUIRED_AFTER(mu1) = Mutex(); // \
// expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
}
//Check argument parsing.
// legal attribute arguments
-Mu aa_var_arg_1 __attribute__((acquired_after(muWrapper.mu)));
-Mu aa_var_arg_2 __attribute__((acquired_after(muDoubleWrapper.muWrapper->mu)));
-Mu aa_var_arg_3 __attribute__((acquired_after(muWrapper.getMu())));
-Mu aa_var_arg_4 __attribute__((acquired_after(*muWrapper.getMuPointer())));
-Mu aa_var_arg_5 __attribute__((acquired_after(&mu1)));
-Mu aa_var_arg_6 __attribute__((acquired_after(muRef)));
-Mu aa_var_arg_7 __attribute__((acquired_after(muDoubleWrapper.getWrapper()->getMu())));
-Mu aa_var_arg_8 __attribute__((acquired_after(muPointer)));
+Mutex aa_var_arg_1 ACQUIRED_AFTER(muWrapper.mu);
+Mutex aa_var_arg_2 ACQUIRED_AFTER(muDoubleWrapper.muWrapper->mu);
+Mutex aa_var_arg_3 ACQUIRED_AFTER(muWrapper.getMu());
+Mutex aa_var_arg_4 ACQUIRED_AFTER(*muWrapper.getMuPointer());
+Mutex aa_var_arg_5 ACQUIRED_AFTER(&mu1);
+Mutex aa_var_arg_6 ACQUIRED_AFTER(muRef);
+Mutex aa_var_arg_7 ACQUIRED_AFTER(muDoubleWrapper.getWrapper()->getMu());
+Mutex aa_var_arg_8 ACQUIRED_AFTER(muPointer);
// illegal attribute arguments
-Mu aa_var_arg_bad_1 __attribute__((acquired_after(1))); // \
- // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
-Mu aa_var_arg_bad_2 __attribute__((acquired_after("mu"))); // \
+Mutex aa_var_arg_bad_1 ACQUIRED_AFTER(1); // \
// expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
-Mu aa_var_arg_bad_3 __attribute__((acquired_after(muDoublePointer))); // \
+Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \
+ // expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}}
+Mutex aa_var_arg_bad_3 ACQUIRED_AFTER(muDoublePointer); // \
// expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
-Mu aa_var_arg_bad_4 __attribute__((acquired_after(umu))); // \
+Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \
// expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}}
-UnlockableMu aa_var_arg_bad_5 __attribute__((acquired_after(mu_aa))); // \
+UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER(mu_aa); // \
// expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'lockable' attribute}}
//-----------------------------------------//
@@ -491,59 +491,59 @@ UnlockableMu aa_var_arg_bad_5 __attribute__((acquired_after(mu_aa))); // \
#error "Should support acquired_before attribute"
#endif
-Mu mu_ab __attribute__((acquired_before(mu1)));
+Mutex mu_ab ACQUIRED_BEFORE(mu1);
-Mu ab_var_noargs __attribute__((acquired_before)); // \
+Mutex ab_var_noargs __attribute__((acquired_before)); // \
// expected-error {{attribute takes at least 1 argument}}
class ABFoo {
private:
- Mu ab_field_noargs __attribute__((acquired_before)); // \
+ Mutex ab_field_noargs __attribute__((acquired_before)); // \
// expected-error {{attribute takes at least 1 argument}}
- Mu ab_field_args __attribute__((acquired_before(mu1)));
+ Mutex ab_field_args ACQUIRED_BEFORE(mu1);
};
-class __attribute__((acquired_before(mu1))) AB { // \
+class ACQUIRED_BEFORE(mu1) AB { // \
// expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
};
-void ab_function() __attribute__((acquired_before(mu1))); // \
+void ab_function() ACQUIRED_BEFORE(mu1); // \
// expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
-void ab_function_params(int gv_lvar __attribute__((acquired_before(mu1)))); // \
+void ab_function_params(int gv_lvar ACQUIRED_BEFORE(mu1)); // \
// expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
void ab_testfn(int y){
- Mu x __attribute__((acquired_before(mu1))) = Mu(); // \
+ Mutex x ACQUIRED_BEFORE(mu1) = Mutex(); // \
// expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
}
-// Note: illegal int ab_int __attribute__((acquired_before(mu1))) will
+// Note: illegal int ab_int ACQUIRED_BEFORE(mu1) will
// be taken care of by warnings that ab__int is not lockable.
//Check argument parsing.
// legal attribute arguments
-Mu ab_var_arg_1 __attribute__((acquired_before(muWrapper.mu)));
-Mu ab_var_arg_2 __attribute__((acquired_before(muDoubleWrapper.muWrapper->mu)));
-Mu ab_var_arg_3 __attribute__((acquired_before(muWrapper.getMu())));
-Mu ab_var_arg_4 __attribute__((acquired_before(*muWrapper.getMuPointer())));
-Mu ab_var_arg_5 __attribute__((acquired_before(&mu1)));
-Mu ab_var_arg_6 __attribute__((acquired_before(muRef)));
-Mu ab_var_arg_7 __attribute__((acquired_before(muDoubleWrapper.getWrapper()->getMu())));
-Mu ab_var_arg_8 __attribute__((acquired_before(muPointer)));
+Mutex ab_var_arg_1 ACQUIRED_BEFORE(muWrapper.mu);
+Mutex ab_var_arg_2 ACQUIRED_BEFORE(muDoubleWrapper.muWrapper->mu);
+Mutex ab_var_arg_3 ACQUIRED_BEFORE(muWrapper.getMu());
+Mutex ab_var_arg_4 ACQUIRED_BEFORE(*muWrapper.getMuPointer());
+Mutex ab_var_arg_5 ACQUIRED_BEFORE(&mu1);
+Mutex ab_var_arg_6 ACQUIRED_BEFORE(muRef);
+Mutex ab_var_arg_7 ACQUIRED_BEFORE(muDoubleWrapper.getWrapper()->getMu());
+Mutex ab_var_arg_8 ACQUIRED_BEFORE(muPointer);
// illegal attribute arguments
-Mu ab_var_arg_bad_1 __attribute__((acquired_before(1))); // \
+Mutex ab_var_arg_bad_1 ACQUIRED_BEFORE(1); // \
// expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
-Mu ab_var_arg_bad_2 __attribute__((acquired_before("mu"))); // \
+Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \
+ // expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}}
+Mutex ab_var_arg_bad_3 ACQUIRED_BEFORE(muDoublePointer); // \
// expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
-Mu ab_var_arg_bad_3 __attribute__((acquired_before(muDoublePointer))); // \
- // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
-Mu ab_var_arg_bad_4 __attribute__((acquired_before(umu))); // \
+Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \
// expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}}
-UnlockableMu ab_var_arg_bad_5 __attribute__((acquired_before(mu_ab))); // \
+UnlockableMu ab_var_arg_bad_5 ACQUIRED_BEFORE(mu_ab); // \
// expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'lockable' attribute}}
@@ -557,65 +557,65 @@ UnlockableMu ab_var_arg_bad_5 __attribute__((acquired_before(mu_ab))); // \
// takes zero or more arguments, all locks (vars/fields)
-void elf_function() __attribute__((exclusive_lock_function));
+void elf_function() EXCLUSIVE_LOCK_FUNCTION();
-void elf_function_args() __attribute__((exclusive_lock_function(mu1, mu2)));
+void elf_function_args() EXCLUSIVE_LOCK_FUNCTION(mu1, mu2);
-int elf_testfn(int y) __attribute__((exclusive_lock_function));
+int elf_testfn(int y) EXCLUSIVE_LOCK_FUNCTION();
int elf_testfn(int y) {
- int x __attribute__((exclusive_lock_function)) = y; // \
+ int x EXCLUSIVE_LOCK_FUNCTION() = y; // \
// expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
return x;
};
-int elf_test_var __attribute__((exclusive_lock_function)); // \
+int elf_test_var EXCLUSIVE_LOCK_FUNCTION(); // \
// expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
class ElfFoo {
private:
- int test_field __attribute__((exclusive_lock_function)); // \
+ int test_field EXCLUSIVE_LOCK_FUNCTION(); // \
// expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
- void test_method() __attribute__((exclusive_lock_function));
+ void test_method() EXCLUSIVE_LOCK_FUNCTION();
};
-class __attribute__((exclusive_lock_function)) ElfTestClass { // \
+class EXCLUSIVE_LOCK_FUNCTION() ElfTestClass { // \
// expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
};
-void elf_fun_params(int lvar __attribute__((exclusive_lock_function))); // \
+void elf_fun_params(int lvar EXCLUSIVE_LOCK_FUNCTION()); // \
// expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
// Check argument parsing.
// legal attribute arguments
-int elf_function_1() __attribute__((exclusive_lock_function(muWrapper.mu)));
-int elf_function_2() __attribute__((exclusive_lock_function(muDoubleWrapper.muWrapper->mu)));
-int elf_function_3() __attribute__((exclusive_lock_function(muWrapper.getMu())));
-int elf_function_4() __attribute__((exclusive_lock_function(*muWrapper.getMuPointer())));
-int elf_function_5() __attribute__((exclusive_lock_function(&mu1)));
-int elf_function_6() __attribute__((exclusive_lock_function(muRef)));
-int elf_function_7() __attribute__((exclusive_lock_function(muDoubleWrapper.getWrapper()->getMu())));
-int elf_function_8() __attribute__((exclusive_lock_function(muPointer)));
-int elf_function_9(Mu x) __attribute__((exclusive_lock_function(1)));
-int elf_function_9(Mu x, Mu y) __attribute__((exclusive_lock_function(1,2)));
+int elf_function_1() EXCLUSIVE_LOCK_FUNCTION(muWrapper.mu);
+int elf_function_2() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);
+int elf_function_3() EXCLUSIVE_LOCK_FUNCTION(muWrapper.getMu());
+int elf_function_4() EXCLUSIVE_LOCK_FUNCTION(*muWrapper.getMuPointer());
+int elf_function_5() EXCLUSIVE_LOCK_FUNCTION(&mu1);
+int elf_function_6() EXCLUSIVE_LOCK_FUNCTION(muRef);
+int elf_function_7() EXCLUSIVE_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());
+int elf_function_8() EXCLUSIVE_LOCK_FUNCTION(muPointer);
+int elf_function_9(Mutex x) EXCLUSIVE_LOCK_FUNCTION(1);
+int elf_function_9(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(1,2);
// illegal attribute arguments
-int elf_function_bad_2() __attribute__((exclusive_lock_function("mu"))); // \
- // expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}}
-int elf_function_bad_3() __attribute__((exclusive_lock_function(muDoublePointer))); // \
+int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \
+ // expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}}
+int elf_function_bad_3() EXCLUSIVE_LOCK_FUNCTION(muDoublePointer); // \
// expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}}
-int elf_function_bad_4() __attribute__((exclusive_lock_function(umu))); // \
+int elf_function_bad_4() EXCLUSIVE_LOCK_FUNCTION(umu); // \
// expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
-int elf_function_bad_1() __attribute__((exclusive_lock_function(1))); // \
+int elf_function_bad_1() EXCLUSIVE_LOCK_FUNCTION(1); // \
// expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
-int elf_function_bad_5(Mu x) __attribute__((exclusive_lock_function(0))); // \
+int elf_function_bad_5(Mutex x) EXCLUSIVE_LOCK_FUNCTION(0); // \
// expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}
-int elf_function_bad_6(Mu x, Mu y) __attribute__((exclusive_lock_function(0))); // \
+int elf_function_bad_6(Mutex x, Mutex y) EXCLUSIVE_LOCK_FUNCTION(0); // \
// expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}
-int elf_function_bad_7() __attribute__((exclusive_lock_function(0))); // \
+int elf_function_bad_7() EXCLUSIVE_LOCK_FUNCTION(0); // \
// expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -629,65 +629,65 @@ int elf_function_bad_7() __attribute__((exclusive_lock_function(0))); // \
// takes zero or more arguments, all locks (vars/fields)
-void slf_function() __attribute__((shared_lock_function));
+void slf_function() SHARED_LOCK_FUNCTION();
-void slf_function_args() __attribute__((shared_lock_function(mu1, mu2)));
+void slf_function_args() SHARED_LOCK_FUNCTION(mu1, mu2);
-int slf_testfn(int y) __attribute__((shared_lock_function));
+int slf_testfn(int y) SHARED_LOCK_FUNCTION();
int slf_testfn(int y) {
- int x __attribute__((shared_lock_function)) = y; // \
+ int x SHARED_LOCK_FUNCTION() = y; // \
// expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
return x;
};
-int slf_test_var __attribute__((shared_lock_function)); // \
+int slf_test_var SHARED_LOCK_FUNCTION(); // \
// expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
-void slf_fun_params(int lvar __attribute__((shared_lock_function))); // \
+void slf_fun_params(int lvar SHARED_LOCK_FUNCTION()); // \
// expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
class SlfFoo {
private:
- int test_field __attribute__((shared_lock_function)); // \
+ int test_field SHARED_LOCK_FUNCTION(); // \
// expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
- void test_method() __attribute__((shared_lock_function));
+ void test_method() SHARED_LOCK_FUNCTION();
};
-class __attribute__((shared_lock_function)) SlfTestClass { // \
+class SHARED_LOCK_FUNCTION() SlfTestClass { // \
// expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
};
// Check argument parsing.
// legal attribute arguments
-int slf_function_1() __attribute__((shared_lock_function(muWrapper.mu)));
-int slf_function_2() __attribute__((shared_lock_function(muDoubleWrapper.muWrapper->mu)));
-int slf_function_3() __attribute__((shared_lock_function(muWrapper.getMu())));
-int slf_function_4() __attribute__((shared_lock_function(*muWrapper.getMuPointer())));
-int slf_function_5() __attribute__((shared_lock_function(&mu1)));
-int slf_function_6() __attribute__((shared_lock_function(muRef)));
-int slf_function_7() __attribute__((shared_lock_function(muDoubleWrapper.getWrapper()->getMu())));
-int slf_function_8() __attribute__((shared_lock_function(muPointer)));
-int slf_function_9(Mu x) __attribute__((shared_lock_function(1)));
-int slf_function_9(Mu x, Mu y) __attribute__((shared_lock_function(1,2)));
+int slf_function_1() SHARED_LOCK_FUNCTION(muWrapper.mu);
+int slf_function_2() SHARED_LOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);
+int slf_function_3() SHARED_LOCK_FUNCTION(muWrapper.getMu());
+int slf_function_4() SHARED_LOCK_FUNCTION(*muWrapper.getMuPointer());
+int slf_function_5() SHARED_LOCK_FUNCTION(&mu1);
+int slf_function_6() SHARED_LOCK_FUNCTION(muRef);
+int slf_function_7() SHARED_LOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());
+int slf_function_8() SHARED_LOCK_FUNCTION(muPointer);
+int slf_function_9(Mutex x) SHARED_LOCK_FUNCTION(1);
+int slf_function_9(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(1,2);
// illegal attribute arguments
-int slf_function_bad_2() __attribute__((shared_lock_function("mu"))); // \
+int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \
+ // expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}}
+int slf_function_bad_3() SHARED_LOCK_FUNCTION(muDoublePointer); // \
// expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}}
-int slf_function_bad_3() __attribute__((shared_lock_function(muDoublePointer))); // \
- // expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}}
-int slf_function_bad_4() __attribute__((shared_lock_function(umu))); // \
+int slf_function_bad_4() SHARED_LOCK_FUNCTION(umu); // \
// expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
-int slf_function_bad_1() __attribute__((shared_lock_function(1))); // \
+int slf_function_bad_1() SHARED_LOCK_FUNCTION(1); // \
// expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
-int slf_function_bad_5(Mu x) __attribute__((shared_lock_function(0))); // \
+int slf_function_bad_5(Mutex x) SHARED_LOCK_FUNCTION(0); // \
// expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}
-int slf_function_bad_6(Mu x, Mu y) __attribute__((shared_lock_function(0))); // \
+int slf_function_bad_6(Mutex x, Mutex y) SHARED_LOCK_FUNCTION(0); // \
// expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}
-int slf_function_bad_7() __attribute__((shared_lock_function(0))); // \
+int slf_function_bad_7() SHARED_LOCK_FUNCTION(0); // \
// expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -705,62 +705,62 @@ int slf_function_bad_7() __attribute__((shared_lock_function(0))); // \
void etf_function() __attribute__((exclusive_trylock_function)); // \
// expected-error {{attribute takes at least 1 argument}}
-void etf_function_args() __attribute__((exclusive_trylock_function(1, mu2)));
+void etf_function_args() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu2);
-void etf_function_arg() __attribute__((exclusive_trylock_function(1)));
+void etf_function_arg() EXCLUSIVE_TRYLOCK_FUNCTION(1);
-int etf_testfn(int y) __attribute__((exclusive_trylock_function(1)));
+int etf_testfn(int y) EXCLUSIVE_TRYLOCK_FUNCTION(1);
int etf_testfn(int y) {
- int x __attribute__((exclusive_trylock_function(1))) = y; // \
+ int x EXCLUSIVE_TRYLOCK_FUNCTION(1) = y; // \
// expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
return x;
};
-int etf_test_var __attribute__((exclusive_trylock_function(1))); // \
+int etf_test_var EXCLUSIVE_TRYLOCK_FUNCTION(1); // \
// expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
class EtfFoo {
private:
- int test_field __attribute__((exclusive_trylock_function(1))); // \
+ int test_field EXCLUSIVE_TRYLOCK_FUNCTION(1); // \
// expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
- void test_method() __attribute__((exclusive_trylock_function(1)));
+ void test_method() EXCLUSIVE_TRYLOCK_FUNCTION(1);
};
-class __attribute__((exclusive_trylock_function(1))) EtfTestClass { // \
+class EXCLUSIVE_TRYLOCK_FUNCTION(1) EtfTestClass { // \
// expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
};
-void etf_fun_params(int lvar __attribute__((exclusive_trylock_function(1)))); // \
+void etf_fun_params(int lvar EXCLUSIVE_TRYLOCK_FUNCTION(1)); // \
// expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
// Check argument parsing.
// legal attribute arguments
-int etf_function_1() __attribute__((exclusive_trylock_function(1, muWrapper.mu)));
-int etf_function_2() __attribute__((exclusive_trylock_function(1, muDoubleWrapper.muWrapper->mu)));
-int etf_function_3() __attribute__((exclusive_trylock_function(1, muWrapper.getMu())));
-int etf_function_4() __attribute__((exclusive_trylock_function(1, *muWrapper.getMuPointer())));
-int etf_function_5() __attribute__((exclusive_trylock_function(1, &mu1)));
-int etf_function_6() __attribute__((exclusive_trylock_function(1, muRef)));
-int etf_function_7() __attribute__((exclusive_trylock_function(1, muDoubleWrapper.getWrapper()->getMu())));
-int etf_functetfn_8() __attribute__((exclusive_trylock_function(1, muPointer)));
-int etf_function_9() __attribute__((exclusive_trylock_function(true)));
+int etf_function_1() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.mu);
+int etf_function_2() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu);
+int etf_function_3() EXCLUSIVE_TRYLOCK_FUNCTION(1, muWrapper.getMu());
+int etf_function_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer());
+int etf_function_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, &mu1);
+int etf_function_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, muRef);
+int etf_function_7() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu());
+int etf_functetfn_8() EXCLUSIVE_TRYLOCK_FUNCTION(1, muPointer);
+int etf_function_9() EXCLUSIVE_TRYLOCK_FUNCTION(true);
// illegal attribute arguments
-int etf_function_bad_1() __attribute__((exclusive_trylock_function(mu1))); // \
+int etf_function_bad_1() EXCLUSIVE_TRYLOCK_FUNCTION(mu1); // \
// expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}}
-int etf_function_bad_2() __attribute__((exclusive_trylock_function("mu"))); // \
+int etf_function_bad_2() EXCLUSIVE_TRYLOCK_FUNCTION("mu"); // \
// expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}}
-int etf_function_bad_3() __attribute__((exclusive_trylock_function(muDoublePointer))); // \
+int etf_function_bad_3() EXCLUSIVE_TRYLOCK_FUNCTION(muDoublePointer); // \
// expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}}
-int etf_function_bad_4() __attribute__((exclusive_trylock_function(1, "mu"))); // \
- // expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}}
-int etf_function_bad_5() __attribute__((exclusive_trylock_function(1, muDoublePointer))); // \
+int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \
+ // expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}
+int etf_function_bad_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoublePointer); // \
// expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}}
-int etf_function_bad_6() __attribute__((exclusive_trylock_function(1, umu))); // \
+int etf_function_bad_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, umu); // \
// expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
@@ -778,63 +778,63 @@ int etf_function_bad_6() __attribute__((exclusive_trylock_function(1, umu))); //
void stf_function() __attribute__((shared_trylock_function)); // \
// expected-error {{attribute takes at least 1 argument}}
-void stf_function_args() __attribute__((shared_trylock_function(1, mu2)));
+void stf_function_args() SHARED_TRYLOCK_FUNCTION(1, mu2);
-void stf_function_arg() __attribute__((shared_trylock_function(1)));
+void stf_function_arg() SHARED_TRYLOCK_FUNCTION(1);
-int stf_testfn(int y) __attribute__((shared_trylock_function(1)));
+int stf_testfn(int y) SHARED_TRYLOCK_FUNCTION(1);
int stf_testfn(int y) {
- int x __attribute__((shared_trylock_function(1))) = y; // \
+ int x SHARED_TRYLOCK_FUNCTION(1) = y; // \
// expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
return x;
};
-int stf_test_var __attribute__((shared_trylock_function(1))); // \
+int stf_test_var SHARED_TRYLOCK_FUNCTION(1); // \
// expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
-void stf_fun_params(int lvar __attribute__((shared_trylock_function(1)))); // \
+void stf_fun_params(int lvar SHARED_TRYLOCK_FUNCTION(1)); // \
// expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
class StfFoo {
private:
- int test_field __attribute__((shared_trylock_function(1))); // \
+ int test_field SHARED_TRYLOCK_FUNCTION(1); // \
// expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
- void test_method() __attribute__((shared_trylock_function(1)));
+ void test_method() SHARED_TRYLOCK_FUNCTION(1);
};
-class __attribute__((shared_trylock_function(1))) StfTestClass { // \
+class SHARED_TRYLOCK_FUNCTION(1) StfTestClass { // \
// expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
};
// Check argument parsing.
// legal attribute arguments
-int stf_function_1() __attribute__((shared_trylock_function(1, muWrapper.mu)));
-int stf_function_2() __attribute__((shared_trylock_function(1, muDoubleWrapper.muWrapper->mu)));
-int stf_function_3() __attribute__((shared_trylock_function(1, muWrapper.getMu())));
-int stf_function_4() __attribute__((shared_trylock_function(1, *muWrapper.getMuPointer())));
-int stf_function_5() __attribute__((shared_trylock_function(1, &mu1)));
-int stf_function_6() __attribute__((shared_trylock_function(1, muRef)));
-int stf_function_7() __attribute__((shared_trylock_function(1, muDoubleWrapper.getWrapper()->getMu())));
-int stf_function_8() __attribute__((shared_trylock_function(1, muPointer)));
-int stf_function_9() __attribute__((shared_trylock_function(true)));
+int stf_function_1() SHARED_TRYLOCK_FUNCTION(1, muWrapper.mu);
+int stf_function_2() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.muWrapper->mu);
+int stf_function_3() SHARED_TRYLOCK_FUNCTION(1, muWrapper.getMu());
+int stf_function_4() SHARED_TRYLOCK_FUNCTION(1, *muWrapper.getMuPointer());
+int stf_function_5() SHARED_TRYLOCK_FUNCTION(1, &mu1);
+int stf_function_6() SHARED_TRYLOCK_FUNCTION(1, muRef);
+int stf_function_7() SHARED_TRYLOCK_FUNCTION(1, muDoubleWrapper.getWrapper()->getMu());
+int stf_function_8() SHARED_TRYLOCK_FUNCTION(1, muPointer);
+int stf_function_9() SHARED_TRYLOCK_FUNCTION(true);
// illegal attribute arguments
-int stf_function_bad_1() __attribute__((shared_trylock_function(mu1))); // \
+int stf_function_bad_1() SHARED_TRYLOCK_FUNCTION(mu1); // \
// expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}}
-int stf_function_bad_2() __attribute__((shared_trylock_function("mu"))); // \
+int stf_function_bad_2() SHARED_TRYLOCK_FUNCTION("mu"); // \
// expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}}
-int stf_function_bad_3() __attribute__((shared_trylock_function(muDoublePointer))); // \
+int stf_function_bad_3() SHARED_TRYLOCK_FUNCTION(muDoublePointer); // \
// expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}}
-int stf_function_bad_4() __attribute__((shared_trylock_function(1, "mu"))); // \
+int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \
+ // expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}
+int stf_function_bad_5() SHARED_TRYLOCK_FUNCTION(1, muDoublePointer); // \
// expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}}
-int stf_function_bad_5() __attribute__((shared_trylock_function(1, muDoublePointer))); // \
- // expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}}
-int stf_function_bad_6() __attribute__((shared_trylock_function(1, umu))); // \
+int stf_function_bad_6() SHARED_TRYLOCK_FUNCTION(1, umu); // \
// expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
@@ -848,65 +848,65 @@ int stf_function_bad_6() __attribute__((shared_trylock_function(1, umu))); // \
// takes zero or more arguments, all locks (vars/fields)
-void uf_function() __attribute__((unlock_function));
+void uf_function() UNLOCK_FUNCTION();
-void uf_function_args() __attribute__((unlock_function(mu1, mu2)));
+void uf_function_args() UNLOCK_FUNCTION(mu1, mu2);
-int uf_testfn(int y) __attribute__((unlock_function));
+int uf_testfn(int y) UNLOCK_FUNCTION();
int uf_testfn(int y) {
- int x __attribute__((unlock_function)) = y; // \
+ int x UNLOCK_FUNCTION() = y; // \
// expected-warning {{'unlock_function' attribute only applies to functions and methods}}
return x;
};
-int uf_test_var __attribute__((unlock_function)); // \
+int uf_test_var UNLOCK_FUNCTION(); // \
// expected-warning {{'unlock_function' attribute only applies to functions and methods}}
class UfFoo {
private:
- int test_field __attribute__((unlock_function)); // \
+ int test_field UNLOCK_FUNCTION(); // \
// expected-warning {{'unlock_function' attribute only applies to functions and methods}}
- void test_method() __attribute__((unlock_function));
+ void test_method() UNLOCK_FUNCTION();
};
-class __attribute__((no_thread_safety_analysis)) UfTestClass { // \
+class NO_THREAD_SAFETY_ANALYSIS UfTestClass { // \
// expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
};
-void uf_fun_params(int lvar __attribute__((unlock_function))); // \
+void uf_fun_params(int lvar UNLOCK_FUNCTION()); // \
// expected-warning {{'unlock_function' attribute only applies to functions and methods}}
// Check argument parsing.
// legal attribute arguments
-int uf_function_1() __attribute__((unlock_function(muWrapper.mu)));
-int uf_function_2() __attribute__((unlock_function(muDoubleWrapper.muWrapper->mu)));
-int uf_function_3() __attribute__((unlock_function(muWrapper.getMu())));
-int uf_function_4() __attribute__((unlock_function(*muWrapper.getMuPointer())));
-int uf_function_5() __attribute__((unlock_function(&mu1)));
-int uf_function_6() __attribute__((unlock_function(muRef)));
-int uf_function_7() __attribute__((unlock_function(muDoubleWrapper.getWrapper()->getMu())));
-int uf_function_8() __attribute__((unlock_function(muPointer)));
-int uf_function_9(Mu x) __attribute__((unlock_function(1)));
-int uf_function_9(Mu x, Mu y) __attribute__((unlock_function(1,2)));
+int uf_function_1() UNLOCK_FUNCTION(muWrapper.mu);
+int uf_function_2() UNLOCK_FUNCTION(muDoubleWrapper.muWrapper->mu);
+int uf_function_3() UNLOCK_FUNCTION(muWrapper.getMu());
+int uf_function_4() UNLOCK_FUNCTION(*muWrapper.getMuPointer());
+int uf_function_5() UNLOCK_FUNCTION(&mu1);
+int uf_function_6() UNLOCK_FUNCTION(muRef);
+int uf_function_7() UNLOCK_FUNCTION(muDoubleWrapper.getWrapper()->getMu());
+int uf_function_8() UNLOCK_FUNCTION(muPointer);
+int uf_function_9(Mutex x) UNLOCK_FUNCTION(1);
+int uf_function_9(Mutex x, Mutex y) UNLOCK_FUNCTION(1,2);
// illegal attribute arguments
-int uf_function_bad_2() __attribute__((unlock_function("mu"))); // \
- // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}}
-int uf_function_bad_3() __attribute__((unlock_function(muDoublePointer))); // \
+int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \
+ // expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}}
+int uf_function_bad_3() UNLOCK_FUNCTION(muDoublePointer); // \
// expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}}
-int uf_function_bad_4() __attribute__((unlock_function(umu))); // \
+int uf_function_bad_4() UNLOCK_FUNCTION(umu); // \
// expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
-int uf_function_bad_1() __attribute__((unlock_function(1))); // \
+int uf_function_bad_1() UNLOCK_FUNCTION(1); // \
// expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
-int uf_function_bad_5(Mu x) __attribute__((unlock_function(0))); // \
+int uf_function_bad_5(Mutex x) UNLOCK_FUNCTION(0); // \
// expected-error {{'unlock_function' attribute parameter 1 is out of bounds: can only be 1, since there is one parameter}}
-int uf_function_bad_6(Mu x, Mu y) __attribute__((unlock_function(0))); // \
+int uf_function_bad_6(Mutex x, Mutex y) UNLOCK_FUNCTION(0); // \
// expected-error {{'unlock_function' attribute parameter 1 is out of bounds: must be between 1 and 2}}
-int uf_function_bad_7() __attribute__((unlock_function(0))); // \
+int uf_function_bad_7() UNLOCK_FUNCTION(0); // \
// expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -923,57 +923,57 @@ int uf_function_bad_7() __attribute__((unlock_function(0))); // \
void lr_function() __attribute__((lock_returned)); // \
// expected-error {{attribute takes one argument}}
-void lr_function_arg() __attribute__((lock_returned(mu1)));
+void lr_function_arg() LOCK_RETURNED(mu1);
void lr_function_args() __attribute__((lock_returned(mu1, mu2))); // \
// expected-error {{attribute takes one argument}}
-int lr_testfn(int y) __attribute__((lock_returned(mu1)));
+int lr_testfn(int y) LOCK_RETURNED(mu1);
int lr_testfn(int y) {
- int x __attribute__((lock_returned(mu1))) = y; // \
+ int x LOCK_RETURNED(mu1) = y; // \
// expected-warning {{'lock_returned' attribute only applies to functions and methods}}
return x;
};
-int lr_test_var __attribute__((lock_returned(mu1))); // \
+int lr_test_var LOCK_RETURNED(mu1); // \
// expected-warning {{'lock_returned' attribute only applies to functions and methods}}
-void lr_fun_params(int lvar __attribute__((lock_returned(mu1)))); // \
+void lr_fun_params(int lvar LOCK_RETURNED(mu1)); // \
// expected-warning {{'lock_returned' attribute only applies to functions and methods}}
class LrFoo {
private:
- int test_field __attribute__((lock_returned(mu1))); // \
+ int test_field LOCK_RETURNED(mu1); // \
// expected-warning {{'lock_returned' attribute only applies to functions and methods}}
- void test_method() __attribute__((lock_returned(mu1)));
+ void test_method() LOCK_RETURNED(mu1);
};
-class __attribute__((lock_returned(mu1))) LrTestClass { // \
+class LOCK_RETURNED(mu1) LrTestClass { // \
// expected-warning {{'lock_returned' attribute only applies to functions and methods}}
};
// Check argument parsing.
// legal attribute arguments
-int lr_function_1() __attribute__((lock_returned(muWrapper.mu)));
-int lr_function_2() __attribute__((lock_returned(muDoubleWrapper.muWrapper->mu)));
-int lr_function_3() __attribute__((lock_returned(muWrapper.getMu())));
-int lr_function_4() __attribute__((lock_returned(*muWrapper.getMuPointer())));
-int lr_function_5() __attribute__((lock_returned(&mu1)));
-int lr_function_6() __attribute__((lock_returned(muRef)));
-int lr_function_7() __attribute__((lock_returned(muDoubleWrapper.getWrapper()->getMu())));
-int lr_function_8() __attribute__((lock_returned(muPointer)));
+int lr_function_1() LOCK_RETURNED(muWrapper.mu);
+int lr_function_2() LOCK_RETURNED(muDoubleWrapper.muWrapper->mu);
+int lr_function_3() LOCK_RETURNED(muWrapper.getMu());
+int lr_function_4() LOCK_RETURNED(*muWrapper.getMuPointer());
+int lr_function_5() LOCK_RETURNED(&mu1);
+int lr_function_6() LOCK_RETURNED(muRef);
+int lr_function_7() LOCK_RETURNED(muDoubleWrapper.getWrapper()->getMu());
+int lr_function_8() LOCK_RETURNED(muPointer);
// illegal attribute arguments
-int lr_function_bad_1() __attribute__((lock_returned(1))); // \
+int lr_function_bad_1() LOCK_RETURNED(1); // \
// expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
-int lr_function_bad_2() __attribute__((lock_returned("mu"))); // \
+int lr_function_bad_2() LOCK_RETURNED("mu"); // \
+ // expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}}
+int lr_function_bad_3() LOCK_RETURNED(muDoublePointer); // \
// expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
-int lr_function_bad_3() __attribute__((lock_returned(muDoublePointer))); // \
- // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
-int lr_function_bad_4() __attribute__((lock_returned(umu))); // \
+int lr_function_bad_4() LOCK_RETURNED(umu); // \
// expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'lockable' attribute}}
@@ -991,56 +991,56 @@ int lr_function_bad_4() __attribute__((lock_returned(umu))); // \
void le_function() __attribute__((locks_excluded)); // \
// expected-error {{attribute takes at least 1 argument}}
-void le_function_arg() __attribute__((locks_excluded(mu1)));
+void le_function_arg() LOCKS_EXCLUDED(mu1);
-void le_function_args() __attribute__((locks_excluded(mu1, mu2)));
+void le_function_args() LOCKS_EXCLUDED(mu1, mu2);
-int le_testfn(int y) __attribute__((locks_excluded(mu1)));
+int le_testfn(int y) LOCKS_EXCLUDED(mu1);
int le_testfn(int y) {
- int x __attribute__((locks_excluded(mu1))) = y; // \
+ int x LOCKS_EXCLUDED(mu1) = y; // \
// expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
return x;
};
-int le_test_var __attribute__((locks_excluded(mu1))); // \
+int le_test_var LOCKS_EXCLUDED(mu1); // \
// expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
-void le_fun_params(int lvar __attribute__((locks_excluded(mu1)))); // \
+void le_fun_params(int lvar LOCKS_EXCLUDED(mu1)); // \
// expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
class LeFoo {
private:
- int test_field __attribute__((locks_excluded(mu1))); // \
+ int test_field LOCKS_EXCLUDED(mu1); // \
// expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
- void test_method() __attribute__((locks_excluded(mu1)));
+ void test_method() LOCKS_EXCLUDED(mu1);
};
-class __attribute__((locks_excluded(mu1))) LeTestClass { // \
+class LOCKS_EXCLUDED(mu1) LeTestClass { // \
// expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
};
// Check argument parsing.
// legal attribute arguments
-int le_function_1() __attribute__((locks_excluded(muWrapper.mu)));
-int le_function_2() __attribute__((locks_excluded(muDoubleWrapper.muWrapper->mu)));
-int le_function_3() __attribute__((locks_excluded(muWrapper.getMu())));
-int le_function_4() __attribute__((locks_excluded(*muWrapper.getMuPointer())));
-int le_function_5() __attribute__((locks_excluded(&mu1)));
-int le_function_6() __attribute__((locks_excluded(muRef)));
-int le_function_7() __attribute__((locks_excluded(muDoubleWrapper.getWrapper()->getMu())));
-int le_function_8() __attribute__((locks_excluded(muPointer)));
+int le_function_1() LOCKS_EXCLUDED(muWrapper.mu);
+int le_function_2() LOCKS_EXCLUDED(muDoubleWrapper.muWrapper->mu);
+int le_function_3() LOCKS_EXCLUDED(muWrapper.getMu());
+int le_function_4() LOCKS_EXCLUDED(*muWrapper.getMuPointer());
+int le_function_5() LOCKS_EXCLUDED(&mu1);
+int le_function_6() LOCKS_EXCLUDED(muRef);
+int le_function_7() LOCKS_EXCLUDED(muDoubleWrapper.getWrapper()->getMu());
+int le_function_8() LOCKS_EXCLUDED(muPointer);
// illegal attribute arguments
-int le_function_bad_1() __attribute__((locks_excluded(1))); // \
- // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
-int le_function_bad_2() __attribute__((locks_excluded("mu"))); // \
+int le_function_bad_1() LOCKS_EXCLUDED(1); // \
// expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
-int le_function_bad_3() __attribute__((locks_excluded(muDoublePointer))); // \
+int le_function_bad_2() LOCKS_EXCLUDED("mu"); // \
+ // expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}}
+int le_function_bad_3() LOCKS_EXCLUDED(muDoublePointer); // \
// expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
-int le_function_bad_4() __attribute__((locks_excluded(umu))); // \
+int le_function_bad_4() LOCKS_EXCLUDED(umu); // \
// expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'lockable' attribute}}
@@ -1058,56 +1058,56 @@ int le_function_bad_4() __attribute__((locks_excluded(umu))); // \
void elr_function() __attribute__((exclusive_locks_required)); // \
// expected-error {{attribute takes at least 1 argument}}
-void elr_function_arg() __attribute__((exclusive_locks_required(mu1)));
+void elr_function_arg() EXCLUSIVE_LOCKS_REQUIRED(mu1);
-void elr_function_args() __attribute__((exclusive_locks_required(mu1, mu2)));
+void elr_function_args() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2);
-int elr_testfn(int y) __attribute__((exclusive_locks_required(mu1)));
+int elr_testfn(int y) EXCLUSIVE_LOCKS_REQUIRED(mu1);
int elr_testfn(int y) {
- int x __attribute__((exclusive_locks_required(mu1))) = y; // \
+ int x EXCLUSIVE_LOCKS_REQUIRED(mu1) = y; // \
// expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
return x;
};
-int elr_test_var __attribute__((exclusive_locks_required(mu1))); // \
+int elr_test_var EXCLUSIVE_LOCKS_REQUIRED(mu1); // \
// expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
-void elr_fun_params(int lvar __attribute__((exclusive_locks_required(mu1)))); // \
+void elr_fun_params(int lvar EXCLUSIVE_LOCKS_REQUIRED(mu1)); // \
// expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
class ElrFoo {
private:
- int test_field __attribute__((exclusive_locks_required(mu1))); // \
+ int test_field EXCLUSIVE_LOCKS_REQUIRED(mu1); // \
// expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
- void test_method() __attribute__((exclusive_locks_required(mu1)));
+ void test_method() EXCLUSIVE_LOCKS_REQUIRED(mu1);
};
-class __attribute__((exclusive_locks_required(mu1))) ElrTestClass { // \
+class EXCLUSIVE_LOCKS_REQUIRED(mu1) ElrTestClass { // \
// expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
};
// Check argument parsing.
// legal attribute arguments
-int elr_function_1() __attribute__((exclusive_locks_required(muWrapper.mu)));
-int elr_function_2() __attribute__((exclusive_locks_required(muDoubleWrapper.muWrapper->mu)));
-int elr_function_3() __attribute__((exclusive_locks_required(muWrapper.getMu())));
-int elr_function_4() __attribute__((exclusive_locks_required(*muWrapper.getMuPointer())));
-int elr_function_5() __attribute__((exclusive_locks_required(&mu1)));
-int elr_function_6() __attribute__((exclusive_locks_required(muRef)));
-int elr_function_7() __attribute__((exclusive_locks_required(muDoubleWrapper.getWrapper()->getMu())));
-int elr_function_8() __attribute__((exclusive_locks_required(muPointer)));
+int elr_function_1() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.mu);
+int elr_function_2() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu);
+int elr_function_3() EXCLUSIVE_LOCKS_REQUIRED(muWrapper.getMu());
+int elr_function_4() EXCLUSIVE_LOCKS_REQUIRED(*muWrapper.getMuPointer());
+int elr_function_5() EXCLUSIVE_LOCKS_REQUIRED(&mu1);
+int elr_function_6() EXCLUSIVE_LOCKS_REQUIRED(muRef);
+int elr_function_7() EXCLUSIVE_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu());
+int elr_function_8() EXCLUSIVE_LOCKS_REQUIRED(muPointer);
// illegal attribute arguments
-int elr_function_bad_1() __attribute__((exclusive_locks_required(1))); // \
+int elr_function_bad_1() EXCLUSIVE_LOCKS_REQUIRED(1); // \
// expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
-int elr_function_bad_2() __attribute__((exclusive_locks_required("mu"))); // \
+int elr_function_bad_2() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \
+ // expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}}
+int elr_function_bad_3() EXCLUSIVE_LOCKS_REQUIRED(muDoublePointer); // \
// expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
-int elr_function_bad_3() __attribute__((exclusive_locks_required(muDoublePointer))); // \
- // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
-int elr_function_bad_4() __attribute__((exclusive_locks_required(umu))); // \
+int elr_function_bad_4() EXCLUSIVE_LOCKS_REQUIRED(umu); // \
// expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
@@ -1126,56 +1126,56 @@ int elr_function_bad_4() __attribute__((exclusive_locks_required(umu))); // \
void slr_function() __attribute__((shared_locks_required)); // \
// expected-error {{attribute takes at least 1 argument}}
-void slr_function_arg() __attribute__((shared_locks_required(mu1)));
+void slr_function_arg() SHARED_LOCKS_REQUIRED(mu1);
-void slr_function_args() __attribute__((shared_locks_required(mu1, mu2)));
+void slr_function_args() SHARED_LOCKS_REQUIRED(mu1, mu2);
-int slr_testfn(int y) __attribute__((shared_locks_required(mu1)));
+int slr_testfn(int y) SHARED_LOCKS_REQUIRED(mu1);
int slr_testfn(int y) {
- int x __attribute__((shared_locks_required(mu1))) = y; // \
+ int x SHARED_LOCKS_REQUIRED(mu1) = y; // \
// expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
return x;
};
-int slr_test_var __attribute__((shared_locks_required(mu1))); // \
+int slr_test_var SHARED_LOCKS_REQUIRED(mu1); // \
// expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
-void slr_fun_params(int lvar __attribute__((shared_locks_required(mu1)))); // \
+void slr_fun_params(int lvar SHARED_LOCKS_REQUIRED(mu1)); // \
// expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
class SlrFoo {
private:
- int test_field __attribute__((shared_locks_required(mu1))); // \
+ int test_field SHARED_LOCKS_REQUIRED(mu1); // \
// expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
- void test_method() __attribute__((shared_locks_required(mu1)));
+ void test_method() SHARED_LOCKS_REQUIRED(mu1);
};
-class __attribute__((shared_locks_required(mu1))) SlrTestClass { // \
+class SHARED_LOCKS_REQUIRED(mu1) SlrTestClass { // \
// expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
};
// Check argument parsing.
// legal attribute arguments
-int slr_function_1() __attribute__((shared_locks_required(muWrapper.mu)));
-int slr_function_2() __attribute__((shared_locks_required(muDoubleWrapper.muWrapper->mu)));
-int slr_function_3() __attribute__((shared_locks_required(muWrapper.getMu())));
-int slr_function_4() __attribute__((shared_locks_required(*muWrapper.getMuPointer())));
-int slr_function_5() __attribute__((shared_locks_required(&mu1)));
-int slr_function_6() __attribute__((shared_locks_required(muRef)));
-int slr_function_7() __attribute__((shared_locks_required(muDoubleWrapper.getWrapper()->getMu())));
-int slr_function_8() __attribute__((shared_locks_required(muPointer)));
+int slr_function_1() SHARED_LOCKS_REQUIRED(muWrapper.mu);
+int slr_function_2() SHARED_LOCKS_REQUIRED(muDoubleWrapper.muWrapper->mu);
+int slr_function_3() SHARED_LOCKS_REQUIRED(muWrapper.getMu());
+int slr_function_4() SHARED_LOCKS_REQUIRED(*muWrapper.getMuPointer());
+int slr_function_5() SHARED_LOCKS_REQUIRED(&mu1);
+int slr_function_6() SHARED_LOCKS_REQUIRED(muRef);
+int slr_function_7() SHARED_LOCKS_REQUIRED(muDoubleWrapper.getWrapper()->getMu());
+int slr_function_8() SHARED_LOCKS_REQUIRED(muPointer);
// illegal attribute arguments
-int slr_function_bad_1() __attribute__((shared_locks_required(1))); // \
- // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
-int slr_function_bad_2() __attribute__((shared_locks_required("mu"))); // \
+int slr_function_bad_1() SHARED_LOCKS_REQUIRED(1); // \
// expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
-int slr_function_bad_3() __attribute__((shared_locks_required(muDoublePointer))); // \
+int slr_function_bad_2() SHARED_LOCKS_REQUIRED("mu"); // \
+ // expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}}
+int slr_function_bad_3() SHARED_LOCKS_REQUIRED(muDoublePointer); // \
// expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
-int slr_function_bad_4() __attribute__((shared_locks_required(umu))); // \
+int slr_function_bad_4() SHARED_LOCKS_REQUIRED(umu); // \
// expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
@@ -1240,43 +1240,43 @@ struct Foomgoper {
// Parsing of member variables and function parameters
//------------------------------------------------------
-Mu gmu;
+Mutex gmu;
class StaticMu {
- static Mu statmu;
+ static Mutex statmu;
};
class FooLate {
public:
- void foo1() __attribute__((exclusive_locks_required(gmu))) { }
- void foo2() __attribute__((exclusive_locks_required(mu))) { }
- void foo3(Mu *m) __attribute__((exclusive_locks_required(m))) { }
- void foo3(FooLate *f) __attribute__((exclusive_locks_required(f->mu))) { }
- void foo4(FooLate *f) __attribute__((exclusive_locks_required(f->mu)));
+ void foo1() EXCLUSIVE_LOCKS_REQUIRED(gmu) { }
+ void foo2() EXCLUSIVE_LOCKS_REQUIRED(mu) { }
+ void foo3(Mutex *m) EXCLUSIVE_LOCKS_REQUIRED(m) { }
+ void foo3(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { }
+ void foo4(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu);
- static void foo5() __attribute__((exclusive_locks_required(mu))); // \
+ static void foo5() EXCLUSIVE_LOCKS_REQUIRED(mu); // \
// expected-error {{'this' cannot be implicitly used in a static member function declaration}}
template <class T>
- void foo6() __attribute__((exclusive_locks_required(T::statmu))) { }
+ void foo6() EXCLUSIVE_LOCKS_REQUIRED(T::statmu) { }
template <class T>
- void foo7(T* f) __attribute__((exclusive_locks_required(f->mu))) { }
+ void foo7(T* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu) { }
- int a __attribute__((guarded_by(gmu)));
- int b __attribute__((guarded_by(mu)));
- int c __attribute__((guarded_by(this->mu)));
+ int a GUARDED_BY(gmu);
+ int b GUARDED_BY(mu);
+ int c GUARDED_BY(this->mu);
- Mu mu;
+ Mutex mu;
};
//-------------------------
// Empty argument lists
//-------------------------
-class __attribute__((lockable)) EmptyArgListsTest {
- void lock() __attribute__((exclusive_lock_function())) { }
- void unlock() __attribute__((unlock_function())) { }
+class LOCKABLE EmptyArgListsTest {
+ void lock() EXCLUSIVE_LOCK_FUNCTION() { }
+ void unlock() UNLOCK_FUNCTION() { }
};
@@ -1285,7 +1285,7 @@ namespace FunctionDefinitionParseTest {
class Foo {
public:
- Mu mu_;
+ Mutex mu_;
void foo1();
void foo2(Foo *f);
};
@@ -1293,17 +1293,17 @@ public:
template <class T>
class Bar {
public:
- Mu mu_;
+ Mutex mu_;
void bar();
};
-void Foo::foo1() __attribute__((exclusive_locks_required(mu_))) { }
-void Foo::foo2(Foo *f) __attribute__((exclusive_locks_required(f->mu_))) { }
+void Foo::foo1() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
+void Foo::foo2(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { }
template <class T>
-void Bar<T>::bar() __attribute__((exclusive_locks_required(mu_))) { }
+void Bar<T>::bar() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }
-void baz(Foo *f) __attribute__((exclusive_locks_required(f->mu_))) { }
+void baz(Foo *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu_) { }
} // end namespace
@@ -1312,13 +1312,15 @@ namespace TestMultiDecl {
class Foo {
public:
- int __attribute__((guarded_by(mu_))) a;
- int __attribute__((guarded_by(mu_))) b, c;
+ int GUARDED_BY(mu_) a;
+ int GUARDED_BY(mu_) b, c;
private:
- Mu mu_;
+ Mutex mu_;
};
+} // end namespace TestMultiDecl
+
namespace NestedClassLateDecl {
@@ -1331,15 +1333,100 @@ class Foo {
void bar2(Bar* b) EXCLUSIVE_LOCKS_REQUIRED(b->mu) { b->a = 0; }
void bar3(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->fooMu) { f->a = 0; }
- Mu mu;
+ Mutex mu;
};
int a GUARDED_BY(fooMu);
- Mu fooMu;
- static Mu fooMuStatic;
+ Mutex fooMu;
+ static Mutex fooMuStatic;
};
}
-} // end namespace TestMultiDecl
+namespace PointerToMemberTest {
+
+// Empty string should be ignored.
+int testEmptyAttribute GUARDED_BY("");
+void testEmptyAttributeFunction() EXCLUSIVE_LOCKS_REQUIRED("");
+
+class Graph {
+public:
+ Mutex mu_;
+
+ static Mutex* get_static_mu() LOCK_RETURNED(&Graph::mu_);
+};
+
+class Node {
+public:
+ void foo() EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_);
+ int a GUARDED_BY(&Graph::mu_);
+};
+
+}
+
+
+namespace SmartPointerTest {
+
+template<class T>
+class smart_ptr {
+ public:
+ T* operator->() { return ptr_; }
+ T& operator*() { return ptr_; }
+
+ private:
+ T* ptr_;
+};
+
+
+Mutex gmu;
+smart_ptr<int> gdat PT_GUARDED_BY(gmu);
+
+
+class MyClass {
+public:
+ Mutex mu_;
+ smart_ptr<Mutex> smu_;
+
+
+ smart_ptr<int> a PT_GUARDED_BY(mu_);
+ int b GUARDED_BY(smu_);
+};
+
+}
+
+
+namespace InheritanceTest {
+
+class LOCKABLE Base {
+ public:
+ void lock() EXCLUSIVE_LOCK_FUNCTION();
+ void unlock() UNLOCK_FUNCTION();
+};
+
+class Base2 { };
+
+class Derived1 : public Base { };
+
+class Derived2 : public Base2, public Derived1 { };
+
+class Derived3 : public Base2 { };
+
+class Foo {
+ Derived1 mu1_;
+ Derived2 mu2_;
+ Derived3 mu3_;
+ int a GUARDED_BY(mu1_);
+ int b GUARDED_BY(mu2_);
+ int c GUARDED_BY(mu3_); // \
+ // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class InheritanceTest::Derived3'}}
+
+ void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1_, mu2_) {
+ a = 0;
+ b = 0;
+ }
+};
+
+}
+
+
diff --git a/test/SemaCXX/warn-unique-enum.cpp b/test/SemaCXX/warn-unique-enum.cpp
new file mode 100644
index 000000000000..59a127807172
--- /dev/null
+++ b/test/SemaCXX/warn-unique-enum.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Wunique-enum
+enum A { A1 = 1, A2 = 1, A3 = 1 }; // expected-warning {{all elements of 'A' are initialized with literals to value 1}} \
+// expected-note {{initialize the last element with the previous element to silence this warning}}
+enum { B1 = 1, B2 = 1, B3 = 1 }; // no warning
+enum C { // expected-warning {{all elements of 'C' are initialized with literals to value 1}}
+ C1 = true,
+ C2 = true // expected-note {{initialize the last element with the previous element to silence this warning}}
+};
+enum D { D1 = 5, D2 = 5L, D3 = 5UL, D4 = 5LL, D5 = 5ULL }; // expected-warning {{all elements of 'D' are initialized with literals to value 5}} \
+// expected-note {{initialize the last element with the previous element to silence this warning}}
+
+// Don't warn on enums with less than 2 elements.
+enum E { E1 = 4 };
+enum F { F1 };
+enum G {};
+
+// Don't warn when integer literals do not initialize the elements.
+enum H { H1 = 4, H_MAX = H1, H_MIN = H1 };
+enum I { I1 = H1, I2 = 4 };
+enum J { J1 = 4, J2 = I2 };
+enum K { K1, K2, K3, K4 };
+
+// Don't crash or warn on this one.
+// rdar://11875995
+enum L {
+ L1 = 0x8000000000000000ULL, L2 = 0x0000000000000001ULL
+};
diff --git a/test/SemaCXX/warn-unused-private-field.cpp b/test/SemaCXX/warn-unused-private-field.cpp
new file mode 100644
index 000000000000..661442db9e9d
--- /dev/null
+++ b/test/SemaCXX/warn-unused-private-field.cpp
@@ -0,0 +1,246 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -verify -std=c++11 %s
+
+class NotFullyDefined {
+ public:
+ NotFullyDefined();
+ private:
+ int y;
+};
+
+class HasUndefinedNestedClass {
+ class Undefined;
+ int unused_;
+};
+
+class HasUndefinedPureVirtualDestructor {
+ virtual ~HasUndefinedPureVirtualDestructor() = 0;
+ int unused_;
+};
+
+class HasDefinedNestedClasses {
+ class DefinedHere {};
+ class DefinedOutside;
+ int unused_; // expected-warning{{private field 'unused_' is not used}}
+};
+class HasDefinedNestedClasses::DefinedOutside {};
+
+class HasUndefinedFriendFunction {
+ friend void undefinedFriendFunction();
+ int unused_;
+};
+
+class HasUndefinedFriendClass {
+ friend class NotFullyDefined;
+ friend class NotDefined;
+ int unused_;
+};
+
+class HasFriend {
+ friend class FriendClass;
+ friend void friendFunction(HasFriend f);
+ int unused_; // expected-warning{{private field 'unused_' is not used}}
+ int used_by_friend_class_;
+ int used_by_friend_function_;
+};
+
+class ClassWithTemplateFriend {
+ template <typename T> friend class TemplateFriend;
+ int used_by_friend_;
+ int unused_;
+};
+
+template <typename T> class TemplateFriend {
+public:
+ TemplateFriend(ClassWithTemplateFriend my_friend) {
+ int var = my_friend.used_by_friend_;
+ }
+};
+
+class FriendClass {
+ HasFriend my_friend_;
+ void use() {
+ my_friend_.used_by_friend_class_ = 42;
+ }
+};
+
+void friendFunction(HasFriend my_friend) {
+ my_friend.used_by_friend_function_ = 42;
+}
+
+class NonTrivialConstructor {
+ public:
+ NonTrivialConstructor() {}
+};
+
+class NonTrivialDestructor {
+ public:
+ ~NonTrivialDestructor() {}
+};
+
+class Trivial {
+ public:
+ Trivial() = default;
+ Trivial(int a) {}
+};
+
+int side_effect() {
+ return 42;
+}
+
+class A {
+ public:
+ A() : primitive_type_(42), default_initializer_(), other_initializer_(42),
+ trivial_(), user_constructor_(42),
+ initialized_with_side_effect_(side_effect()) {
+ used_ = 42;
+ attr_used_ = 42; // expected-warning{{'attr_used_' was marked unused but was used}}
+ }
+
+ A(int x, A* a) : pointer_(a) {}
+
+ private:
+ int primitive_type_; // expected-warning{{private field 'primitive_type_' is not used}}
+ A* pointer_; // expected-warning{{private field 'pointer_' is not used}}
+ int no_initializer_; // expected-warning{{private field 'no_initializer_' is not used}}
+ int default_initializer_; // expected-warning{{private field 'default_initializer_' is not used}}
+ int other_initializer_; // expected-warning{{private field 'other_initializer_' is not used}}
+ int used_, unused_; // expected-warning{{private field 'unused_' is not used}}
+ int in_class_initializer_ = 42; // expected-warning{{private field 'in_class_initializer_' is not used}}
+ int in_class_initializer_with_side_effect_ = side_effect();
+ Trivial trivial_initializer_ = Trivial(); // expected-warning{{private field 'trivial_initializer_' is not used}}
+ Trivial non_trivial_initializer_ = Trivial(42);
+ int initialized_with_side_effect_;
+ static int static_fields_are_ignored_;
+
+ Trivial trivial_; // expected-warning{{private field 'trivial_' is not used}}
+ Trivial user_constructor_;
+ NonTrivialConstructor non_trivial_constructor_;
+ NonTrivialDestructor non_trivial_destructor_;
+
+ int attr_ __attribute__((unused));
+ int attr_used_ __attribute__((unused));
+};
+
+class EverythingUsed {
+ public:
+ EverythingUsed() : as_array_index_(0), var_(by_initializer_) {
+ var_ = sizeof(sizeof_);
+ int *use = &by_reference_;
+ int test[2];
+ test[as_array_index_] = 42;
+ }
+
+ template<class T>
+ void useStuff(T t) {
+ by_template_function_ = 42;
+ }
+
+ private:
+ int var_;
+ int sizeof_;
+ int by_reference_;
+ int by_template_function_;
+ int as_array_index_;
+ int by_initializer_;
+};
+
+class HasFeatureTest {
+#if __has_feature(attribute_unused_on_fields)
+ int unused_; // expected-warning{{private field 'unused_' is not used}}
+ int unused2_ __attribute__((unused)); // no-warning
+#endif
+};
+
+namespace templates {
+class B {
+ template <typename T> void f(T t);
+ int a;
+};
+} // namespace templates
+
+namespace mutual_friends {
+// Undefined methods make mutual friends undefined.
+class A {
+ int a;
+ friend class B;
+ void doSomethingToAOrB();
+};
+class B {
+ int b;
+ friend class A;
+};
+
+// Undefined friends do not make a mutual friend undefined.
+class C {
+ int c;
+ void doSomethingElse() {}
+ friend class E;
+ friend class D;
+};
+class D {
+ int d; // expected-warning{{private field 'd' is not used}}
+ friend class C;
+};
+
+// Undefined nested classes make mutual friends undefined.
+class F {
+ int f;
+ class G;
+ friend class H;
+};
+class H {
+ int h;
+ friend class F;
+};
+} // namespace mutual_friends
+
+namespace anonymous_structs_unions {
+class A {
+ private:
+ // FIXME: Look at the DeclContext for anonymous structs/unions.
+ union {
+ int *Aligner;
+ unsigned char Data[8];
+ };
+};
+union S {
+ private:
+ int *Aligner;
+ unsigned char Data[8];
+};
+} // namespace anonymous_structs_unions
+
+namespace pr13413 {
+class A {
+ A() : p_(__null), b_(false), a_(this), p2_(nullptr) {}
+ void* p_; // expected-warning{{private field 'p_' is not used}}
+ bool b_; // expected-warning{{private field 'b_' is not used}}
+ A* a_; // expected-warning{{private field 'a_' is not used}}
+ void* p2_; // expected-warning{{private field 'p2_' is not used}}
+};
+}
+
+namespace pr13543 {
+ void f(int);
+ void f(char);
+ struct S {
+ S() : p(&f) {}
+ private:
+ void (*p)(int); // expected-warning{{private field 'p' is not used}}
+ };
+
+ struct A { int n; };
+ struct B {
+ B() : a(A()) {}
+ B(char) {}
+ B(int n) : a{n}, b{(f(n), 0)} {}
+ private:
+ A a = A(); // expected-warning{{private field 'a' is not used}}
+ A b;
+ };
+
+ struct X { ~X(); };
+ class C {
+ X x[4]; // no-warning
+ };
+}
diff --git a/test/SemaCXX/warn-unused-value.cpp b/test/SemaCXX/warn-unused-value.cpp
index 1c0263c581c1..072ee60f1f35 100644
--- a/test/SemaCXX/warn-unused-value.cpp
+++ b/test/SemaCXX/warn-unused-value.cpp
@@ -12,7 +12,7 @@ namespace test0 {
// pointer to volatile has side effect (thus no warning)
Box* box = new Box;
box->i; // expected-warning {{expression result unused}}
- box->j;
+ box->j; // expected-warning {{expression result unused}}
}
}