aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX')
-rw-r--r--test/SemaCXX/2008-01-11-BadWarning.cpp5
-rw-r--r--test/SemaCXX/MicrosoftCompatibility.cpp158
-rw-r--r--test/SemaCXX/MicrosoftExtensions.cpp61
-rw-r--r--test/SemaCXX/PR10243.cpp2
-rw-r--r--test/SemaCXX/PR10458.cpp7
-rw-r--r--test/SemaCXX/PR5086-ambig-resolution-enum.cpp2
-rw-r--r--test/SemaCXX/PR7944.cpp2
-rw-r--r--test/SemaCXX/PR8012.cpp2
-rw-r--r--test/SemaCXX/PR9572.cpp2
-rw-r--r--test/SemaCXX/PR9902.cpp2
-rw-r--r--test/SemaCXX/PR9908.cpp2
-rw-r--r--test/SemaCXX/abstract.cpp2
-rw-r--r--test/SemaCXX/address-of.cpp11
-rw-r--r--test/SemaCXX/aggregate-initialization.cpp8
-rw-r--r--test/SemaCXX/alias-template.cpp2
-rw-r--r--test/SemaCXX/alignof-sizeof-reference.cpp15
-rw-r--r--test/SemaCXX/ambig-user-defined-conversions.cpp2
-rw-r--r--test/SemaCXX/ambiguous-builtin-unary-operator.cpp2
-rw-r--r--test/SemaCXX/array-bounds-ptr-arith.cpp33
-rw-r--r--test/SemaCXX/array-bounds.cpp80
-rw-r--r--test/SemaCXX/attr-cxx0x.cpp14
-rw-r--r--test/SemaCXX/attr-deprecated.cpp4
-rw-r--r--test/SemaCXX/auto-cxx0x.cpp4
-rw-r--r--test/SemaCXX/auto-cxx98.cpp7
-rw-r--r--test/SemaCXX/auto-subst-failure.cpp2
-rw-r--r--test/SemaCXX/bool.cpp7
-rw-r--r--test/SemaCXX/builtin-ptrtomember-ambig.cpp2
-rw-r--r--test/SemaCXX/builtin-ptrtomember-overload-1.cpp2
-rw-r--r--test/SemaCXX/builtin-ptrtomember-overload.cpp2
-rw-r--r--test/SemaCXX/cast-conversion.cpp5
-rw-r--r--test/SemaCXX/class.cpp13
-rw-r--r--test/SemaCXX/compare.cpp11
-rw-r--r--test/SemaCXX/complex-init-list.cpp14
-rw-r--r--test/SemaCXX/conditional-expr.cpp23
-rw-r--r--test/SemaCXX/conversion-delete-expr.cpp2
-rw-r--r--test/SemaCXX/convert-to-bool.cpp6
-rw-r--r--test/SemaCXX/cxx0x-class.cpp28
-rw-r--r--test/SemaCXX/cxx0x-compat.cpp24
-rw-r--r--test/SemaCXX/cxx0x-constexpr-const.cpp2
-rw-r--r--test/SemaCXX/cxx0x-cursory-default-delete.cpp4
-rw-r--r--test/SemaCXX/cxx0x-defaulted-functions.cpp2
-rw-r--r--test/SemaCXX/cxx0x-delegating-ctors.cpp2
-rw-r--r--test/SemaCXX/cxx0x-deleted-default-ctor.cpp14
-rw-r--r--test/SemaCXX/cxx0x-initializer-scalars.cpp34
-rw-r--r--test/SemaCXX/cxx0x-nontrivial-union.cpp2
-rw-r--r--test/SemaCXX/cxx0x-return-init-list.cpp6
-rw-r--r--test/SemaCXX/cxx0x-type-convert-construct.cpp21
-rw-r--r--test/SemaCXX/cxx98-compat-pedantic.cpp11
-rw-r--r--test/SemaCXX/cxx98-compat.cpp30
-rw-r--r--test/SemaCXX/decl-init-ref.cpp2
-rw-r--r--test/SemaCXX/decltype-crash.cpp2
-rw-r--r--test/SemaCXX/decltype-overloaded-functions.cpp14
-rw-r--r--test/SemaCXX/decltype-pr4444.cpp2
-rw-r--r--test/SemaCXX/decltype-pr4448.cpp2
-rw-r--r--test/SemaCXX/decltype-this.cpp2
-rw-r--r--test/SemaCXX/decltype.cpp2
-rw-r--r--test/SemaCXX/defaulted-ctor-loop.cpp2
-rw-r--r--test/SemaCXX/delete.cpp2
-rw-r--r--test/SemaCXX/deleted-function.cpp2
-rw-r--r--test/SemaCXX/deleted-operator.cpp13
-rw-r--r--test/SemaCXX/dependent-auto.cpp2
-rw-r--r--test/SemaCXX/dependent-noexcept-unevaluated.cpp2
-rw-r--r--test/SemaCXX/dependent-types.cpp2
-rw-r--r--test/SemaCXX/destructor.cpp2
-rw-r--r--test/SemaCXX/enum-bitfield.cpp2
-rw-r--r--test/SemaCXX/enum-scoped.cpp2
-rw-r--r--test/SemaCXX/explicit.cpp147
-rw-r--r--test/SemaCXX/expression-traits.cpp40
-rw-r--r--test/SemaCXX/expressions.cpp75
-rw-r--r--test/SemaCXX/for-range-examples.cpp2
-rw-r--r--test/SemaCXX/for-range-no-std.cpp3
-rw-r--r--test/SemaCXX/for-range-unused.cpp2
-rw-r--r--test/SemaCXX/function-overload-typo-crash.cpp20
-rw-r--r--test/SemaCXX/function-redecl.cpp71
-rw-r--r--test/SemaCXX/generalized-initializers.cpp23
-rw-r--r--test/SemaCXX/generic-selection.cpp2
-rw-r--r--test/SemaCXX/i-c-e-cxx.cpp6
-rw-r--r--test/SemaCXX/implicit-exception-spec.cpp2
-rw-r--r--test/SemaCXX/issue547.cpp2
-rw-r--r--test/SemaCXX/libstdcxx_is_pod_hack.cpp4
-rw-r--r--test/SemaCXX/linkage-spec.cpp13
-rw-r--r--test/SemaCXX/literal-operators.cpp40
-rw-r--r--test/SemaCXX/literal-type.cpp2
-rw-r--r--test/SemaCXX/member-expr.cpp30
-rw-r--r--test/SemaCXX/member-init.cpp20
-rw-r--r--test/SemaCXX/microsoft-cxx0x.cpp10
-rw-r--r--test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp14
-rw-r--r--test/SemaCXX/nested-name-spec.cpp10
-rw-r--r--test/SemaCXX/new-array-size-conv.cpp4
-rw-r--r--test/SemaCXX/new-delete.cpp19
-rw-r--r--test/SemaCXX/null_in_arithmetic_ops.cpp14
-rw-r--r--test/SemaCXX/nullptr.cpp2
-rw-r--r--test/SemaCXX/nullptr_in_arithmetic_ops.cpp2
-rw-r--r--test/SemaCXX/out-of-line-def-mismatch.cpp24
-rw-r--r--test/SemaCXX/overload-0x.cpp11
-rw-r--r--test/SemaCXX/overload-call.cpp9
-rw-r--r--test/SemaCXX/overloaded-builtin-operators-0x.cpp2
-rw-r--r--test/SemaCXX/overloaded-name.cpp17
-rw-r--r--test/SemaCXX/overloaded-operator-decl.cpp5
-rw-r--r--test/SemaCXX/overloaded-operator.cpp6
-rw-r--r--test/SemaCXX/ptrtomember-overload-resolution.cpp2
-rw-r--r--test/SemaCXX/ptrtomember.cpp18
-rw-r--r--test/SemaCXX/redeclared-alias-template.cpp2
-rw-r--r--test/SemaCXX/redeclared-auto.cpp2
-rw-r--r--test/SemaCXX/ref-init-ambiguous.cpp2
-rw-r--r--test/SemaCXX/references.cpp3
-rw-r--r--test/SemaCXX/return-noreturn.cpp99
-rw-r--r--test/SemaCXX/rval-references-examples.cpp2
-rw-r--r--test/SemaCXX/rval-references.cpp2
-rw-r--r--test/SemaCXX/scope-check.cpp38
-rw-r--r--test/SemaCXX/static-assert.cpp2
-rw-r--r--test/SemaCXX/switch-0x.cpp2
-rw-r--r--test/SemaCXX/trailing-return-0x.cpp2
-rw-r--r--test/SemaCXX/trivial-constructor.cpp2
-rw-r--r--test/SemaCXX/trivial-destructor.cpp2
-rw-r--r--test/SemaCXX/type-traits.cpp36
-rw-r--r--test/SemaCXX/typo-correction.cpp31
-rw-r--r--test/SemaCXX/underlying_type.cpp2
-rw-r--r--test/SemaCXX/uninit-variables-conditional.cpp2
-rw-r--r--test/SemaCXX/uninit-variables.cpp36
-rw-r--r--test/SemaCXX/uninitialized.cpp74
-rw-r--r--test/SemaCXX/unknown-anytype.cpp11
-rw-r--r--test/SemaCXX/unused-functions.cpp2
-rw-r--r--test/SemaCXX/user-defined-conversions.cpp15
-rw-r--r--test/SemaCXX/using-decl-templates.cpp17
-rw-r--r--test/SemaCXX/value-initialization.cpp2
-rw-r--r--test/SemaCXX/vararg-non-pod.cpp1
-rw-r--r--test/SemaCXX/virtual-override.cpp2
-rw-r--r--test/SemaCXX/virtuals.cpp2
-rw-r--r--test/SemaCXX/warn-assignment-condition.cpp6
-rw-r--r--test/SemaCXX/warn-bad-memaccess.cpp17
-rw-r--r--test/SemaCXX/warn-bool-conversion.cpp12
-rw-r--r--test/SemaCXX/warn-dangling-field.cpp37
-rw-r--r--test/SemaCXX/warn-literal-conversion.cpp18
-rw-r--r--test/SemaCXX/warn-memset-bad-sizeof.cpp38
-rw-r--r--test/SemaCXX/warn-missing-noreturn.cpp34
-rw-r--r--test/SemaCXX/warn-sign-compare.cpp72
-rw-r--r--test/SemaCXX/warn-sign-conversion.cpp80
-rw-r--r--test/SemaCXX/warn-string-conversion.cpp18
-rw-r--r--test/SemaCXX/warn-thread-safety-analysis.cpp1422
-rw-r--r--test/SemaCXX/warn-thread-safety-parsing.cpp1255
-rw-r--r--test/SemaCXX/warn-unreachable.cpp8
-rw-r--r--test/SemaCXX/warn-unused-comparison.cpp94
-rw-r--r--test/SemaCXX/warn-unused-value.cpp15
-rw-r--r--test/SemaCXX/warn-weak-vtables.cpp27
145 files changed, 4525 insertions, 449 deletions
diff --git a/test/SemaCXX/2008-01-11-BadWarning.cpp b/test/SemaCXX/2008-01-11-BadWarning.cpp
new file mode 100644
index 000000000000..b84e7c1cf862
--- /dev/null
+++ b/test/SemaCXX/2008-01-11-BadWarning.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wall %s
+// rdar://5683899
+void** f(void **Buckets, unsigned NumBuckets) {
+ return Buckets + NumBuckets;
+}
diff --git a/test/SemaCXX/MicrosoftCompatibility.cpp b/test/SemaCXX/MicrosoftCompatibility.cpp
new file mode 100644
index 000000000000..dfc47d6fc956
--- /dev/null
+++ b/test/SemaCXX/MicrosoftCompatibility.cpp
@@ -0,0 +1,158 @@
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions
+
+
+
+namespace ms_conversion_rules {
+
+void f(float a);
+void f(int a);
+
+void test()
+{
+ long a = 0;
+ f((long)0);
+ f(a);
+}
+
+}
+
+
+
+namespace ms_protected_scope {
+ struct C { C(); };
+
+ int jump_over_variable_init(bool b) {
+ if (b)
+ goto foo; // expected-warning {{illegal goto into protected scope}}
+ C c; // expected-note {{jump bypasses variable initialization}}
+ foo:
+ return 1;
+ }
+
+struct Y {
+ ~Y();
+};
+
+void jump_over_var_with_dtor() {
+ goto end; // expected-warning{{goto into protected scope}}
+ Y y; // expected-note {{jump bypasses variable initialization}}
+ end:
+ ;
+}
+
+ void jump_over_variable_case(int c) {
+ switch (c) {
+ case 0:
+ int x = 56; // expected-note {{jump bypasses variable initialization}}
+ case 1: // expected-error {{switch case is in protected scope}}
+ x = 10;
+ }
+ }
+
+
+void exception_jump() {
+ goto l2; // expected-error {{illegal goto into protected scope}}
+ try { // expected-note {{jump bypasses initialization of try block}}
+ l2: ;
+ } catch(int) {
+ }
+}
+
+int jump_over_indirect_goto() {
+ static void *ps[] = { &&a0 };
+ goto *&&a0; // expected-warning {{goto into protected scope}}
+ int a = 3; // expected-note {{jump bypasses variable initialization}}
+ a0:
+ return 0;
+}
+
+}
+
+
+
+namespace ms_using_declaration_bug {
+
+class A {
+public:
+ int f();
+};
+
+class B : public A {
+private:
+ using A::f;
+};
+
+class C : public B {
+private:
+ using B::f; // expected-warning {{using declaration refers to inaccessible member 'ms_using_declaration_bug::B::f', which refers to accessible member 'ms_using_declaration_bug::A::f', accepted for Microsoft compatibility}}
+};
+
+}
+
+
+namespace MissingTypename {
+
+template<class T> class A {
+public:
+ typedef int TYPE;
+};
+
+template<class T> class B {
+public:
+ typedef int TYPE;
+};
+
+
+template<class T, class U>
+class C : private A<T>, public B<U> {
+public:
+ typedef A<T> Base1;
+ typedef B<U> Base2;
+ typedef A<U> Base3;
+
+ A<T>::TYPE a1; // expected-warning {{missing 'typename' prior to dependent type name}}
+ Base1::TYPE a2; // expected-warning {{missing 'typename' prior to dependent type name}}
+
+ B<U>::TYPE a3; // expected-warning {{missing 'typename' prior to dependent type name}}
+ Base2::TYPE a4; // expected-warning {{missing 'typename' prior to dependent type name}}
+
+ A<U>::TYPE a5; // expected-error {{missing 'typename' prior to dependent type name}}
+ Base3::TYPE a6; // expected-error {{missing 'typename' prior to dependent type name}}
+ };
+
+class D {
+public:
+ typedef int Type;
+};
+
+template <class T>
+void function_missing_typename(const T::Type param)// expected-warning {{missing 'typename' prior to dependent type name}}
+{
+ const T::Type var = 2; // expected-warning {{missing 'typename' prior to dependent type name}}
+}
+
+template void function_missing_typename<D>(const D::Type param);
+
+}
+
+
+
+namespace lookup_dependent_bases_id_expr {
+
+template<class T> class A {
+public:
+ int var;
+};
+
+
+template<class T>
+class B : public A<T> {
+public:
+ void f() {
+ var = 3;
+ }
+};
+
+template class B<int>;
+
+} \ No newline at end of file
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index 9b03feb53909..63e058b36daa 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -81,6 +81,10 @@ struct M {
float __stdcall subtractP();
};
+// __unaligned handling
+typedef char __unaligned *aligned_type;
+
+
template<typename T> void h1(T (__stdcall M::* const )()) { }
void m1() {
@@ -148,40 +152,6 @@ template <class T>
void BB<T>::f(int g = 0) { } // expected-warning {{redefinition of default argument}}
-namespace MissingTypename {
-
-template<class T> class A {
-public:
- typedef int TYPE;
-};
-
-template<class T> class B {
-public:
- typedef int TYPE;
-};
-
-
-template<class T, class U>
-class C : private A<T>, public B<U> {
-public:
- typedef A<T> Base1;
- typedef B<U> Base2;
- typedef A<U> Base3;
-
- A<T>::TYPE a1; // expected-warning {{missing 'typename' prior to dependent type name}}
- Base1::TYPE a2; // expected-warning {{missing 'typename' prior to dependent type name}}
-
- B<U>::TYPE a3; // expected-warning {{missing 'typename' prior to dependent type name}}
- Base2::TYPE a4; // expected-warning {{missing 'typename' prior to dependent type name}}
-
- A<U>::TYPE a5; // expected-error {{missing 'typename' prior to dependent type name}}
- Base3::TYPE a6; // expected-error {{missing 'typename' prior to dependent type name}}
- };
-
-}
-
-
-
extern void static_func();
void static_func(); // expected-note {{previous declaration is here}}
@@ -209,26 +179,6 @@ void pointer_to_integral_type_conv(char* ptr) {
sh = (short)ptr;
}
-namespace ms_using_declaration_bug {
-
-class A {
-public:
- int f();
-};
-
-class B : public A {
-private:
- using A::f;
-};
-
-class C : public B {
-private:
- using B::f; // expected-warning {{using declaration refers to inaccessible member 'ms_using_declaration_bug::B::f', which refers to accessible member 'ms_using_declaration_bug::A::f', accepted for Microsoft compatibility}}
-};
-
-}
-
-
namespace friend_as_a_forward_decl {
@@ -251,4 +201,5 @@ void f()
Z* b;
}
- } \ No newline at end of file
+}
+
diff --git a/test/SemaCXX/PR10243.cpp b/test/SemaCXX/PR10243.cpp
index 9a5851049803..129ff80e2d2e 100644
--- a/test/SemaCXX/PR10243.cpp
+++ b/test/SemaCXX/PR10243.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
struct S; // expected-note 4{{forward declaration of 'S'}}
diff --git a/test/SemaCXX/PR10458.cpp b/test/SemaCXX/PR10458.cpp
new file mode 100644
index 000000000000..57588ebcf1f0
--- /dev/null
+++ b/test/SemaCXX/PR10458.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
+
+void f() {
+ int arr[] = { 1, 2, 3 };
+ for (auto &i : arr) { // expected-warning {{'auto' type specifier is a C++11 extension}} expected-warning {{range-based for loop is a C++11 extension}}
+ }
+}
diff --git a/test/SemaCXX/PR5086-ambig-resolution-enum.cpp b/test/SemaCXX/PR5086-ambig-resolution-enum.cpp
index 720566a69b05..b5aac5f09c16 100644
--- a/test/SemaCXX/PR5086-ambig-resolution-enum.cpp
+++ b/test/SemaCXX/PR5086-ambig-resolution-enum.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
class C {
public:
diff --git a/test/SemaCXX/PR7944.cpp b/test/SemaCXX/PR7944.cpp
index a998a15c3e0b..51b3f6bccec0 100644
--- a/test/SemaCXX/PR7944.cpp
+++ b/test/SemaCXX/PR7944.cpp
@@ -8,5 +8,5 @@ struct A { B* b() { return new B; } };
void g() {
A a;
- MACRO(a.b->f()); // expected-error{{base of member reference is a function}}
+ MACRO(a.b->f()); // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
}
diff --git a/test/SemaCXX/PR8012.cpp b/test/SemaCXX/PR8012.cpp
index f2f07ad36400..9cfc2b000c01 100644
--- a/test/SemaCXX/PR8012.cpp
+++ b/test/SemaCXX/PR8012.cpp
@@ -1,3 +1,3 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
void foo (int operator+); // expected-error{{cannot be the name of a parameter}}
diff --git a/test/SemaCXX/PR9572.cpp b/test/SemaCXX/PR9572.cpp
index 25c0c017b7f6..b0bbfa6318cd 100644
--- a/test/SemaCXX/PR9572.cpp
+++ b/test/SemaCXX/PR9572.cpp
@@ -3,7 +3,7 @@ class Base {
virtual ~Base(); // expected-note {{implicitly declared private here}}
};
struct Foo : public Base { // expected-error {{base class 'Base' has private destructor}}
- const int kBlah = 3; // expected-warning {{accepted as a C++0x extension}}
+ const int kBlah = 3; // expected-warning {{accepted as a C++11 extension}}
Foo();
};
struct Bar : public Foo {
diff --git a/test/SemaCXX/PR9902.cpp b/test/SemaCXX/PR9902.cpp
index ec76789b9657..80086e445c5d 100644
--- a/test/SemaCXX/PR9902.cpp
+++ b/test/SemaCXX/PR9902.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
template <class _Tp, class _Up, bool = false>
struct __allocator_traits_rebind
diff --git a/test/SemaCXX/PR9908.cpp b/test/SemaCXX/PR9908.cpp
index 3b98b724dd87..fc090cc42f92 100644
--- a/test/SemaCXX/PR9908.cpp
+++ b/test/SemaCXX/PR9908.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
template <class _Tp, class _Up>
struct __allocator_traits_rebind
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
index c262230962f9..b164d9eda6a5 100644
--- a/test/SemaCXX/abstract.cpp
+++ b/test/SemaCXX/abstract.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
#ifndef __GXX_EXPERIMENTAL_CXX0X__
#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
diff --git a/test/SemaCXX/address-of.cpp b/test/SemaCXX/address-of.cpp
index a7e712b04c1d..69fcaff8f1ed 100644
--- a/test/SemaCXX/address-of.cpp
+++ b/test/SemaCXX/address-of.cpp
@@ -33,3 +33,14 @@ void test2() {
// PR clang/3222
void xpto();
void (*xyz)(void) = &xpto;
+
+struct PR11066 {
+ static int foo(short);
+ static int foo(float);
+ void test();
+};
+
+void PR11066::test() {
+ int (PR11066::*ptr)(int) = & &PR11066::foo; // expected-error{{address expression must be an lvalue or a function designator}}
+}
+
diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp
index b9e69b00b7fe..3c0e4483c441 100644
--- a/test/SemaCXX/aggregate-initialization.cpp
+++ b/test/SemaCXX/aggregate-initialization.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// Verify that we can't initialize non-aggregates with an initializer
// list.
-// FIXME: Note that due to a (likely) standard bug, this is technically an
-// aggregate.
+// Note that due to a (likely) standard bug, this is technically an aggregate,
+// but we do not treat it as one.
struct NonAggr1 {
NonAggr1(int) { }
@@ -24,7 +24,7 @@ struct NonAggr4 {
virtual void f();
};
-NonAggr1 na1 = { 17 };
+NonAggr1 na1 = { 17 }; // expected-error{{non-aggregate type 'NonAggr1' cannot be initialized with an initializer list}}
NonAggr2 na2 = { 17 }; // expected-error{{non-aggregate type 'NonAggr2' cannot be initialized with an initializer list}}
NonAggr3 na3 = { 17 }; // expected-error{{non-aggregate type 'NonAggr3' cannot be initialized with an initializer list}}
NonAggr4 na4 = { 17 }; // expected-error{{non-aggregate type 'NonAggr4' cannot be initialized with an initializer list}}
diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp
index f29a9327dab3..6cff4206faa4 100644
--- a/test/SemaCXX/alias-template.cpp
+++ b/test/SemaCXX/alias-template.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -std=c++0x %s
+// RUN: %clang_cc1 -verify -std=c++11 %s
namespace RedeclAliasTypedef {
template<typename U> using T = int;
diff --git a/test/SemaCXX/alignof-sizeof-reference.cpp b/test/SemaCXX/alignof-sizeof-reference.cpp
index 93ba203ae112..ccdf45e52dd7 100644
--- a/test/SemaCXX/alignof-sizeof-reference.cpp
+++ b/test/SemaCXX/alignof-sizeof-reference.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
struct s0; // expected-note {{forward declaration}}
char ar[sizeof(s0&)]; // expected-error {{invalid application of 'sizeof' to an incomplete type}}
@@ -8,14 +8,15 @@ void test() {
static_assert(sizeof(r) == 1, "bad size");
}
-void f(); // expected-note{{candidate function}}
-void f(int); // expected-note{{candidate function}}
+void f(); // expected-note{{possible target for call}}
+void f(int); // expected-note{{possible target for call}}
void g() {
- sizeof(&f); // expected-error{{cannot resolve overloaded function 'f' from context}}
+ sizeof(&f); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} \
+ // expected-warning{{expression result unused}}
}
-template<typename T> void f_template(); // expected-note{{candidate function}}
-template<typename T> void f_template(T*); // expected-note{{candidate function}}
+template<typename T> void f_template(); // expected-note{{possible target for call}}
+template<typename T> void f_template(T*); // expected-note{{possible target for call}}
void rdar9659191() {
- (void)alignof(f_template<int>); // expected-error{{cannot resolve overloaded function 'f_template' from context}}
+ (void)alignof(f_template<int>); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
}
diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp
index bf45e5d4d888..1a3c102f034c 100644
--- a/test/SemaCXX/ambig-user-defined-conversions.cpp
+++ b/test/SemaCXX/ambig-user-defined-conversions.cpp
@@ -53,7 +53,7 @@ namespace test1 {
E b;
f1(b); // expected-error {{call to 'f1' is ambiguous}}
// ambiguous because b -> C via constructor and
- // b → A via constructor or conversion function.
+ // b -> A via constructor or conversion function.
}
}
diff --git a/test/SemaCXX/ambiguous-builtin-unary-operator.cpp b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp
index 836e319f8404..6e96e03f7245 100644
--- a/test/SemaCXX/ambiguous-builtin-unary-operator.cpp
+++ b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
struct A {
operator int&();
diff --git a/test/SemaCXX/array-bounds-ptr-arith.cpp b/test/SemaCXX/array-bounds-ptr-arith.cpp
new file mode 100644
index 000000000000..ce1ace6f2fb6
--- /dev/null
+++ b/test/SemaCXX/array-bounds-ptr-arith.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -verify -Warray-bounds-pointer-arithmetic %s
+
+void swallow (const char *x) { (void)x; }
+void test_pointer_arithmetic(int n) {
+ const char hello[] = "Hello world!"; // expected-note 2 {{declared here}}
+ const char *helloptr = hello;
+
+ swallow("Hello world!" + 6); // no-warning
+ swallow("Hello world!" - 6); // expected-warning {{refers before the beginning of the array}}
+ swallow("Hello world!" + 14); // expected-warning {{refers past the end of the array}}
+ swallow("Hello world!" + 13); // no-warning
+
+ swallow(hello + 6); // no-warning
+ swallow(hello - 6); // expected-warning {{refers before the beginning of the array}}
+ swallow(hello + 14); // expected-warning {{refers past the end of the array}}
+ swallow(hello + 13); // no-warning
+
+ swallow(helloptr + 6); // no-warning
+ swallow(helloptr - 6); // no-warning
+ swallow(helloptr + 14); // no-warning
+ swallow(helloptr + 13); // no-warning
+
+ double numbers[2]; // expected-note {{declared here}}
+ swallow((char*)numbers + sizeof(double)); // no-warning
+ swallow((char*)numbers + 60); // expected-warning {{refers past the end of the array}}
+
+ char buffer[5]; // expected-note 2 {{declared here}}
+ // TODO: Add FixIt notes for adding parens around non-ptr part of arith expr
+ swallow(buffer + sizeof("Hello")-1); // expected-warning {{refers past the end of the array}}
+ swallow(buffer + (sizeof("Hello")-1)); // no-warning
+ if (n > 0 && n <= 6) swallow(buffer + 6 - n); // expected-warning {{refers past the end of the array}}
+ if (n > 0 && n <= 6) swallow(buffer + (6 - n)); // no-warning
+}
diff --git a/test/SemaCXX/array-bounds.cpp b/test/SemaCXX/array-bounds.cpp
index 3bd6c35420d7..555ac33af559 100644
--- a/test/SemaCXX/array-bounds.cpp
+++ b/test/SemaCXX/array-bounds.cpp
@@ -3,9 +3,11 @@
int foo() {
int x[2]; // expected-note 4 {{array 'x' declared here}}
int y[2]; // expected-note 2 {{array 'y' declared here}}
+ int z[1]; // expected-note {{array 'z' declared here}}
int *p = &y[2]; // no-warning
(void) sizeof(x[2]); // no-warning
y[2] = 2; // expected-warning {{array index of '2' indexes past the end of an array (that contains 2 elements)}}
+ z[1] = 'x'; // expected-warning {{array index of '1' indexes past the end of an array (that contains 1 element)}}
return x[2] + // expected-warning {{array index of '2' indexes past the end of an array (that contains 2 elements)}}
y[-1] + // expected-warning {{array index of '-1' indexes before the beginning of the array}}
x[sizeof(x)] + // expected-warning {{array index of '8' indexes past the end of an array (that contains 2 elements)}}
@@ -24,8 +26,8 @@ void f1(int a[1]) {
int val = a[3]; // no warning for function argumnet
}
-void f2(const int (&a)[1]) { // expected-note {{declared here}}
- int val = a[3]; // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 elements)}}
+void f2(const int (&a)[2]) { // expected-note {{declared here}}
+ int val = a[3]; // expected-warning {{array index of '3' indexes past the end of an array (that contains 2 elements)}}
}
void test() {
@@ -35,15 +37,20 @@ void test() {
s2.a[3] = 0; // no warning for 0-sized array
union {
- short a[2]; // expected-note {{declared here}}
+ short a[2]; // expected-note 4 {{declared here}}
char c[4];
} u;
u.a[3] = 1; // expected-warning {{array index of '3' indexes past the end of an array (that contains 2 elements)}}
u.c[3] = 1; // no warning
+ short *p = &u.a[2]; // no warning
+ p = &u.a[3]; // expected-warning {{array index of '3' indexes past the end of an array (that contains 2 elements)}}
+ *(&u.a[2]) = 1; // expected-warning {{array index of '2' indexes past the end of an array (that contains 2 elements)}}
+ *(&u.a[3]) = 1; // expected-warning {{array index of '3' indexes past the end of an array (that contains 2 elements)}}
+ *(&u.c[3]) = 1; // no warning
const int const_subscript = 3;
- int array[1]; // expected-note {{declared here}}
- array[const_subscript] = 0; // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 elements)}}
+ int array[2]; // expected-note {{declared here}}
+ array[const_subscript] = 0; // expected-warning {{array index of '3' indexes past the end of an array (that contains 2 elements)}}
int *ptr;
ptr[3] = 0; // no warning for pointer references
@@ -58,8 +65,8 @@ void test() {
const char str2[] = "foo"; // expected-note {{declared here}}
char c2 = str2[5]; // expected-warning {{array index of '5' indexes past the end of an array (that contains 4 elements)}}
- int (*array_ptr)[1];
- (*array_ptr)[3] = 1; // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 elements)}}
+ int (*array_ptr)[2];
+ (*array_ptr)[3] = 1; // expected-warning {{array index of '3' indexes past the end of an array (that contains 2 elements)}}
}
template <int I> struct S {
@@ -151,8 +158,7 @@ void test_switch() {
enum enumA { enumA_A, enumA_B, enumA_C, enumA_D, enumA_E };
enum enumB { enumB_X, enumB_Y, enumB_Z };
static enum enumB myVal = enumB_X;
-void test_nested_switch()
-{
+void test_nested_switch() {
switch (enumA_E) { // expected-warning {{no case matching constant}}
switch (myVal) { // expected-warning {{enumeration values 'enumB_X' and 'enumB_Z' not handled in switch}}
case enumB_Y: ;
@@ -173,3 +179,59 @@ void test_all_enums_covered(enum Values v) {
}
x[2] = 0; // no-warning
}
+
+namespace tailpad {
+ struct foo {
+ char c1[1]; // expected-note {{declared here}}
+ int x;
+ char c2[1];
+ };
+
+ char bar(struct foo *F) {
+ return F->c1[3]; // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 element)}}
+ return F->c2[3]; // no warning, foo could have tail padding allocated.
+ }
+}
+
+namespace metaprogramming {
+#define ONE 1
+ struct foo { char c[ONE]; }; // expected-note {{declared here}}
+ template <int N> struct bar { char c[N]; }; // expected-note {{declared here}}
+
+ char test(foo *F, bar<1> *B) {
+ return F->c[3] + // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 element)}}
+ B->c[3]; // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 element)}}
+ }
+}
+
+void bar(int x) {}
+int test_more() {
+ int foo[5]; // expected-note 5 {{array 'foo' declared here}}
+ bar(foo[5]); // expected-warning {{array index of '5' indexes past the end of an array (that contains 5 elements)}}
+ ++foo[5]; // expected-warning {{array index of '5' indexes past the end of an array (that contains 5 elements)}}
+ if (foo[6]) // expected-warning {{array index of '6' indexes past the end of an array (that contains 5 elements)}}
+ return --foo[6]; // expected-warning {{array index of '6' indexes past the end of an array (that contains 5 elements)}}
+ else
+ return foo[5]; // expected-warning {{array index of '5' indexes past the end of an array (that contains 5 elements)}}
+}
+
+void test_pr10771() {
+ double foo[4096]; // expected-note {{array 'foo' declared here}}
+
+ ((char*)foo)[sizeof(foo) - 1] = '\0'; // no-warning
+ *(((char*)foo) + sizeof(foo) - 1) = '\0'; // no-warning
+
+ ((char*)foo)[sizeof(foo)] = '\0'; // expected-warning {{array index of '32768' indexes past the end of an array (that contains 32768 elements)}}
+
+ // TODO: This should probably warn, too.
+ *(((char*)foo) + sizeof(foo)) = '\0'; // no-warning
+}
+
+int test_pr11007_aux(const char * restrict, ...);
+
+// Test checking with varargs.
+void test_pr11007() {
+ double a[5]; // expected-note {{array 'a' declared here}}
+ test_pr11007_aux("foo", a[1000]); // expected-warning {{array index of '1000' indexes past the end of an array}}
+}
+
diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp
index 725f0182db50..de9d7d1c2a6e 100644
--- a/test/SemaCXX/attr-cxx0x.cpp
+++ b/test/SemaCXX/attr-cxx0x.cpp
@@ -1,15 +1,15 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-int align_illegal [[align(3)]]; //expected-error {{requested alignment is not a power of 2}}
-char align_big [[align(int)]];
-int align_small [[align(1)]]; // FIXME: this should be rejected
-int align_multiple [[align(1), align(8), align(1)]];
+int align_illegal alignas(3); //expected-error {{requested alignment is not a power of 2}}
+char align_big alignas(int);
+int align_small alignas(1); // FIXME: this should be rejected
+int align_multiple alignas(1) alignas(8) alignas(1);
struct align_member {
- int member [[align(8)]];
+ int member alignas(8);
};
-typedef char align_typedef [[align(8)]];
+typedef char align_typedef alignas(8);
template<typename T> using align_alias_template = align_typedef;
static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong");
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index fe7c833d322b..945aff363eb1 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -198,7 +198,7 @@ namespace test6 {
};
void testA() {
A x; // expected-warning {{'A' is deprecated}}
- x = a0;
+ x = a0; // expected-warning {{'A' is deprecated}}
}
enum B {
@@ -218,7 +218,7 @@ namespace test6 {
};
void testC() {
C<int>::Enum x; // expected-warning {{'Enum' is deprecated}}
- x = C<int>::c0;
+ x = C<int>::c0; // expected-warning {{'Enum' is deprecated}}
}
template <class T> struct D {
diff --git a/test/SemaCXX/auto-cxx0x.cpp b/test/SemaCXX/auto-cxx0x.cpp
index f9246beff92a..a8f9e84423a7 100644
--- a/test/SemaCXX/auto-cxx0x.cpp
+++ b/test/SemaCXX/auto-cxx0x.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
void f() {
- auto int a; // expected-warning {{'auto' storage class specifier is redundant and will be removed in future releases}}
+ auto int a; // expected-warning {{'auto' storage class specifier is not permitted in C++11, and will not be supported in future releases}}
int auto b; // expected-error{{cannot combine with previous 'int' declaration specifier}}
}
diff --git a/test/SemaCXX/auto-cxx98.cpp b/test/SemaCXX/auto-cxx98.cpp
index fe028114880a..6c401ba11a93 100644
--- a/test/SemaCXX/auto-cxx98.cpp
+++ b/test/SemaCXX/auto-cxx98.cpp
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
void f() {
- auto int a;
- int auto b;
+ auto int a; // expected-warning {{'auto' storage class specifier is redundant and incompatible with C++11}}
+ int auto b; // expected-warning {{'auto' storage class specifier is redundant and incompatible with C++11}}
+ auto c; // expected-warning {{C++11 extension}} expected-error {{requires an initializer}}
+ static auto d = 0; // expected-warning {{C++11 extension}}
+ auto static e = 0; // expected-warning {{C++11 extension}}
}
diff --git a/test/SemaCXX/auto-subst-failure.cpp b/test/SemaCXX/auto-subst-failure.cpp
index 442c7e82ccdb..b323dfc6b049 100644
--- a/test/SemaCXX/auto-subst-failure.cpp
+++ b/test/SemaCXX/auto-subst-failure.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
void f() {
auto a = f(); // expected-error {{variable has incomplete type 'void'}}
diff --git a/test/SemaCXX/bool.cpp b/test/SemaCXX/bool.cpp
index 726fa6cb60fc..2b3ab68848eb 100644
--- a/test/SemaCXX/bool.cpp
+++ b/test/SemaCXX/bool.cpp
@@ -25,6 +25,9 @@ void static_assert_arg_is_bool(T x) {
void test2() {
int n = 2;
- static_assert_arg_is_bool(n && 4); // expected-warning {{use of logical && with constant operand}}
- static_assert_arg_is_bool(n || 5); // expected-warning {{use of logical || with constant operand}}
+ static_assert_arg_is_bool(n && 4); // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
+ static_assert_arg_is_bool(n || 5); // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
}
diff --git a/test/SemaCXX/builtin-ptrtomember-ambig.cpp b/test/SemaCXX/builtin-ptrtomember-ambig.cpp
index 32a893dafcef..61e347879a75 100644
--- a/test/SemaCXX/builtin-ptrtomember-ambig.cpp
+++ b/test/SemaCXX/builtin-ptrtomember-ambig.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
struct A {};
diff --git a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
index f736394a4caa..2d93c6b2dff3 100644
--- a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
+++ b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
struct A {};
struct E {};
diff --git a/test/SemaCXX/builtin-ptrtomember-overload.cpp b/test/SemaCXX/builtin-ptrtomember-overload.cpp
index 6c132366199b..c7b5173a4fbe 100644
--- a/test/SemaCXX/builtin-ptrtomember-overload.cpp
+++ b/test/SemaCXX/builtin-ptrtomember-overload.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
struct A {};
diff --git a/test/SemaCXX/cast-conversion.cpp b/test/SemaCXX/cast-conversion.cpp
index 80707d13d20b..dd2bc98e02cc 100644
--- a/test/SemaCXX/cast-conversion.cpp
+++ b/test/SemaCXX/cast-conversion.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
struct R {
R(int);
@@ -8,7 +8,8 @@ struct A {
A(R);
};
-struct B { // expected-note 3 {{candidate constructor (the implicit copy constructor) not viable}}
+struct B { // expected-note 3 {{candidate constructor (the implicit copy constructor) not viable}} \
+ expected-note 3 {{candidate constructor (the implicit move constructor) not viable}}
B(A); // expected-note 3 {{candidate constructor not viable}}
};
diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp
index 44fa0ce7ec9f..160f365f4bbf 100644
--- a/test/SemaCXX/class.cpp
+++ b/test/SemaCXX/class.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
class C {
public:
- auto int errx; // expected-error {{error: storage class specified for a member declaration}}
+ auto int errx; // expected-error {{error: storage class specified for a member declaration}} expected-warning {{'auto' storage class specifier is redundant}}
register int erry; // expected-error {{error: storage class specified for a member declaration}}
extern int errz; // expected-error {{error: storage class specified for a member declaration}}
@@ -34,11 +34,12 @@ public:
enum E1 { en1, en2 };
- int i = 0; // expected-warning {{in-class initialization of non-static data member accepted as a C++0x extension}}
+ int i = 0; // expected-warning {{in-class initialization of non-static data member accepted as a C++11 extension}}
static int si = 0; // expected-error {{non-const static data member must be initialized out of line}}
static const NestedC ci = 0; // expected-error {{static data member of type 'const C::NestedC' must be initialized out of line}}
static const int nci = vs; // expected-error {{in-class initializer is not a constant expression}}
static const int vi = 0;
+ static const volatile int cvi = 0; // ok, illegal in C++11
static const E evi = 0;
void m() {
@@ -172,8 +173,8 @@ namespace rdar8367341 {
float foo();
struct A {
- static const float x = 5.0f; // expected-warning {{in-class initializer for static data member of type 'const float' is a C++0x extension}}
- static const float y = foo(); // expected-warning {{in-class initializer for static data member of type 'const float' is a C++0x extension}} expected-error {{in-class initializer is not a constant expression}}
+ static const float x = 5.0f; // expected-warning {{in-class initializer for static data member of type 'const float' is a GNU extension}}
+ static const float y = foo(); // expected-warning {{in-class initializer for static data member of type 'const float' is a GNU extension}} expected-error {{in-class initializer is not a constant expression}}
};
}
@@ -188,3 +189,7 @@ void f() {
S::c; // expected-error {{invalid use of nonstatic data member}}
}
}
+
+struct PR9989 {
+ static int const PR9989_Member = sizeof PR9989_Member;
+};
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index ca8af2186f74..28e2dd0ad51a 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -212,3 +212,14 @@ static const unsigned int kMax = 0;
int pr7536() {
return (kMax > 0);
}
+
+// -Wsign-compare should not warn when ?: operands have different signedness.
+// This will be caught by -Wsign-conversion
+void test3() {
+ unsigned long a;
+ signed long b;
+ (void) (true ? a : b);
+ (void) (true ? (unsigned int)a : (signed int)b);
+ (void) (true ? b : a);
+ (void) (true ? (unsigned char)b : (signed char)a);
+}
diff --git a/test/SemaCXX/complex-init-list.cpp b/test/SemaCXX/complex-init-list.cpp
new file mode 100644
index 000000000000..e75833a37dbc
--- /dev/null
+++ b/test/SemaCXX/complex-init-list.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -pedantic
+
+// This file tests the clang extension which allows initializing the components
+// of a complex number individually using an initialization list. Basically,
+// if you have an explicit init list for a complex number that contains two
+// initializers, this extension kicks in to turn it into component-wise
+// initialization.
+//
+// See also the testcase for the C version of this extension in
+// test/Sema/complex-init-list.c.
+
+// Basic testcase
+// (No pedantic warning is necessary because _Complex is not part of C++.)
+_Complex float valid1 = { 1.0f, 2.0f };
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index b95700e9ba18..5648d022b522 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++0x -Wsign-compare %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -Wsign-conversion %s
// C++ rules for ?: are a lot stricter than C rules, and have to take into
// account more conversion options.
@@ -180,12 +180,12 @@ void test()
unsigned long test0 = 5;
- test0 = test0 ? (long) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
- test0 = test0 ? (int) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
- test0 = test0 ? (short) test0 : test0; // expected-warning {{operands of ? are integers of different signs}}
- test0 = test0 ? test0 : (long) test0; // expected-warning {{operands of ? are integers of different signs}}
- test0 = test0 ? test0 : (int) test0; // expected-warning {{operands of ? are integers of different signs}}
- test0 = test0 ? test0 : (short) test0; // expected-warning {{operands of ? are integers of different signs}}
+ test0 = test0 ? (long) test0 : test0; // expected-warning {{operand of ? changes signedness: 'long' to 'unsigned long'}}
+ test0 = test0 ? (int) test0 : test0; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
+ test0 = test0 ? (short) test0 : test0; // expected-warning {{operand of ? changes signedness: 'short' to 'unsigned long'}}
+ test0 = test0 ? test0 : (long) test0; // expected-warning {{operand of ? changes signedness: 'long' to 'unsigned long'}}
+ test0 = test0 ? test0 : (int) test0; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
+ test0 = test0 ? test0 : (short) test0; // expected-warning {{operand of ? changes signedness: 'short' to 'unsigned long'}}
test0 = test0 ? test0 : (long) 10;
test0 = test0 ? test0 : (int) 10;
test0 = test0 ? test0 : (short) 10;
@@ -193,8 +193,15 @@ void test()
test0 = test0 ? (int) 10 : test0;
test0 = test0 ? (short) 10 : test0;
+ int test1;
test0 = test0 ? EVal : test0;
- test0 = test0 ? EVal : (int) test0;
+ test1 = test0 ? EVal : (int) test0;
+
+ test0 = test0 ? EVal : test1; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
+ test0 = test0 ? test1 : EVal; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}}
+
+ test1 = test0 ? EVal : (int) test0;
+ test1 = test0 ? (int) test0 : EVal;
// Note the thing that this does not test: since DR446, various situations
// *must* create a separate temporary copy of class objects. This can only
diff --git a/test/SemaCXX/conversion-delete-expr.cpp b/test/SemaCXX/conversion-delete-expr.cpp
index 862ae5ae02bb..0f298a819fa3 100644
--- a/test/SemaCXX/conversion-delete-expr.cpp
+++ b/test/SemaCXX/conversion-delete-expr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// Test1
struct B {
diff --git a/test/SemaCXX/convert-to-bool.cpp b/test/SemaCXX/convert-to-bool.cpp
index 4cd22e90c0e0..c9a355549fdf 100644
--- a/test/SemaCXX/convert-to-bool.cpp
+++ b/test/SemaCXX/convert-to-bool.cpp
@@ -8,7 +8,7 @@ struct ConvToInt {
};
struct ExplicitConvToBool {
- explicit operator bool(); // expected-warning{{explicit conversion functions are a C++0x extension}}
+ explicit operator bool(); // expected-warning{{explicit conversion functions are a C++11 extension}}
};
void test_conv_to_bool(ConvToBool ctb, ConvToInt cti, ExplicitConvToBool ecb) {
@@ -39,7 +39,7 @@ void test_conv_to_bool(ConvToBool ctb, ConvToInt cti, ExplicitConvToBool ecb) {
void accepts_bool(bool) { } // expected-note{{candidate function}}
struct ExplicitConvToRef {
- explicit operator int&(); // expected-warning{{explicit conversion functions are a C++0x extension}}
+ explicit operator int&(); // expected-warning{{explicit conversion functions are a C++11 extension}}
};
void test_explicit_bool(ExplicitConvToBool ecb) {
@@ -56,7 +56,7 @@ void test_explicit_conv_to_ref(ExplicitConvToRef ecr) {
struct A { };
struct B { };
struct C {
- explicit operator A&(); // expected-warning{{explicit conversion functions are a C++0x extension}}
+ explicit operator A&(); // expected-warning{{explicit conversion functions are a C++11 extension}}
operator B&(); // expected-note{{candidate}}
};
diff --git a/test/SemaCXX/cxx0x-class.cpp b/test/SemaCXX/cxx0x-class.cpp
new file mode 100644
index 000000000000..3527ccb55577
--- /dev/null
+++ b/test/SemaCXX/cxx0x-class.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+int vs = 0;
+
+class C {
+public:
+ struct NestedC {
+ NestedC(int);
+ };
+
+ int i = 0;
+ static int si = 0; // expected-error {{non-const static data member must be initialized out of line}}
+ static const NestedC ci = 0; // expected-error {{static data member of type 'const C::NestedC' must be initialized out of line}}
+ static const int nci = vs; // expected-error {{in-class initializer is not a constant expression}}
+ static const int vi = 0;
+ static const volatile int cvi = 0; // expected-error {{static const volatile data member must be initialized out of line}}
+};
+
+namespace rdar8367341 {
+ float foo();
+
+ struct A {
+ static const float x = 5.0f; // expected-warning {{GNU extension}} expected-note {{use 'constexpr' specifier to silence this warning}}
+ static const float y = foo(); // expected-warning {{GNU extension}} expected-note {{use 'constexpr' specifier to silence this warning}} expected-error {{in-class initializer is not a constant expression}}
+ static constexpr float x2 = 5.0f;
+ static constexpr float y2 = foo(); // expected-error {{must be initialized by a constant expression}}
+ };
+}
diff --git a/test/SemaCXX/cxx0x-compat.cpp b/test/SemaCXX/cxx0x-compat.cpp
new file mode 100644
index 000000000000..a01b26c5f91b
--- /dev/null
+++ b/test/SemaCXX/cxx0x-compat.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++0x-compat -verify %s
+
+namespace N {
+ template<typename T> void f(T) {} // expected-note {{here}}
+ namespace M {
+ template void f<int>(int); // expected-warning {{explicit instantiation of 'N::f' must occur in namespace 'N'}}
+ }
+}
+
+template<typename T> void f(T) {} // expected-note {{here}}
+namespace M {
+ template void f<int>(int); // expected-warning {{explicit instantiation of 'f' must occur in the global namespace}}
+}
+
+void f() {
+ auto int n = 0; // expected-warning {{'auto' storage class specifier is redundant and incompatible with C++11}}
+}
+
+int n;
+struct S {
+ char c;
+}
+s = { n }, // expected-warning {{non-constant-expression cannot be narrowed from type 'int' to 'char' in initializer list in C++11}} expected-note {{explicit cast}}
+t = { 1234 }; // expected-warning {{constant expression evaluates to 1234 which cannot be narrowed to type 'char' in C++11}} expected-warning {{changes value}} expected-note {{explicit cast}}
diff --git a/test/SemaCXX/cxx0x-constexpr-const.cpp b/test/SemaCXX/cxx0x-constexpr-const.cpp
index 79e6dda3e11c..197edeb097b6 100644
--- a/test/SemaCXX/cxx0x-constexpr-const.cpp
+++ b/test/SemaCXX/cxx0x-constexpr-const.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
constexpr int x = 1;
constexpr int id(int x) { return x; }
diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
index 61aee0e45633..17933c2f009a 100644
--- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp
+++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
struct non_copiable {
non_copiable(const non_copiable&) = delete; // expected-note {{marked deleted here}}
@@ -35,7 +35,7 @@ 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& operator = (const bad_decls&) const = default; // expected-error {{may not have 'const' or 'volatile' qualifiers}}
+ bad_decls& operator = (const bad_decls&) const = default; // expected-error {{may not have 'const', 'constexpr' or 'volatile' qualifiers}}
};
struct A {}; struct B {};
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 86c5fd10e23c..d01f63bedb6b 100644
--- a/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
void fn() = default; // expected-error {{only special member}}
struct foo {
diff --git a/test/SemaCXX/cxx0x-delegating-ctors.cpp b/test/SemaCXX/cxx0x-delegating-ctors.cpp
index a3e6ff3b4f92..2d49f0fc599d 100644
--- a/test/SemaCXX/cxx0x-delegating-ctors.cpp
+++ b/test/SemaCXX/cxx0x-delegating-ctors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
struct foo {
int i;
diff --git a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
index dcb6ba2790be..16c56642c06b 100644
--- a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
+++ b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
struct non_trivial {
non_trivial();
@@ -118,3 +118,15 @@ struct late_delete {
late_delete();
};
late_delete::late_delete() = default; // expected-error {{would delete it}}
+
+// See also rdar://problem/8125400.
+namespace empty {
+ static union {}; // expected-error {{deleted constructor}} expected-note {{here}}
+ static union { union {}; };
+ static union { struct {}; };
+ static union { union { union {}; }; };
+ static union { union { struct {}; }; };
+ static union { struct { union {}; }; }; // expected-error {{deleted constructor}} expected-note {{here}}
+ static union { struct { struct {}; }; };
+}
+
diff --git a/test/SemaCXX/cxx0x-initializer-scalars.cpp b/test/SemaCXX/cxx0x-initializer-scalars.cpp
new file mode 100644
index 000000000000..41fc2193891c
--- /dev/null
+++ b/test/SemaCXX/cxx0x-initializer-scalars.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+namespace integral {
+
+ void initialization() {
+ { const int a{}; static_assert(a == 0, ""); }
+ { const int a = {}; static_assert(a == 0, ""); }
+ { const int a{1}; static_assert(a == 1, ""); }
+ { const int a = {1}; static_assert(a == 1, ""); }
+ { const int a{1, 2}; } // expected-error {{excess elements}}
+ { const int a = {1, 2}; } // expected-error {{excess elements}}
+ // FIXME: Redundant warnings.
+ { const short a{100000}; } // expected-error {{cannot be narrowed}} expected-note {{inserting an explicit cast}} expected-warning {{changes value}}
+ { const short a = {100000}; } // expected-error {{cannot be narrowed}} expected-note {{inserting an explicit cast}} expected-warning {{changes value}}
+ }
+
+ int direct_usage() {
+ int ar[10];
+ (void) ar[{1}]; // expected-error {{array subscript is not an integer}}
+
+ return {1};
+ }
+
+ void inline_init() {
+ (void) int{1};
+ (void) new int{1};
+ }
+
+ struct A {
+ int i;
+ A() : i{1} {}
+ };
+
+}
diff --git a/test/SemaCXX/cxx0x-nontrivial-union.cpp b/test/SemaCXX/cxx0x-nontrivial-union.cpp
index 666e64be66ab..6275af6bac52 100644
--- a/test/SemaCXX/cxx0x-nontrivial-union.cpp
+++ b/test/SemaCXX/cxx0x-nontrivial-union.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
struct non_trivial {
non_trivial();
diff --git a/test/SemaCXX/cxx0x-return-init-list.cpp b/test/SemaCXX/cxx0x-return-init-list.cpp
index 2005a7f9f676..b786922b71a8 100644
--- a/test/SemaCXX/cxx0x-return-init-list.cpp
+++ b/test/SemaCXX/cxx0x-return-init-list.cpp
@@ -1,17 +1,17 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// This test checks for a teeny tiny subset of the functionality in
-// the C++0x generalized initializer lists feature, which happens to
+// the C++11 generalized initializer lists feature, which happens to
// be used in libstdc++ 4.5. We accept only this syntax so that Clang
// can handle the libstdc++ 4.5 headers.
int test0(int i) {
- return { i }; // expected-warning{{generalized initializer lists are a C++0x extension unsupported in Clang}}
+ return { i }; // expected-warning{{generalized initializer lists are a C++11 extension unsupported in Clang}}
}
template<typename T, typename U>
T test1(U u) {
- return { u }; // expected-warning{{generalized initializer lists are a C++0x extension unsupported in Clang}}
+ return { u }; // expected-warning{{generalized initializer lists are a C++11 extension unsupported in Clang}}
}
template int test1(char);
diff --git a/test/SemaCXX/cxx0x-type-convert-construct.cpp b/test/SemaCXX/cxx0x-type-convert-construct.cpp
new file mode 100644
index 000000000000..6a7fe45281f5
--- /dev/null
+++ b/test/SemaCXX/cxx0x-type-convert-construct.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=gnu++11 -fsyntax-only -verify %s
+
+void f() {
+ char *u8str;
+ u8str = u8"a UTF-8 string"; // expected-error {{assigning to 'char *' from incompatible type 'const char [15]'}}
+ char16_t *ustr;
+ ustr = u"a UTF-16 string"; // expected-error {{assigning to 'char16_t *' from incompatible type 'const char16_t [16]'}}
+ char32_t *Ustr;
+ Ustr = U"a UTF-32 string"; // expected-error {{assigning to 'char32_t *' from incompatible type 'const char32_t [16]'}}
+
+ char *Rstr;
+ Rstr = R"foo(a raw string)foo"; // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+ wchar_t *LRstr;
+ LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}}
+ char *u8Rstr;
+ u8Rstr = u8R"foo(a UTF-8 raw string)foo"; // expected-error {{assigning to 'char *' from incompatible type 'const char [19]'}}
+ char16_t *uRstr;
+ uRstr = uR"foo(a UTF-16 raw string)foo"; // expected-error {{assigning to 'char16_t *' from incompatible type 'const char16_t [20]'}}
+ char32_t *URstr;
+ URstr = UR"foo(a UTF-32 raw string)foo"; // expected-error {{assigning to 'char32_t *' from incompatible type 'const char32_t [20]'}}
+}
diff --git a/test/SemaCXX/cxx98-compat-pedantic.cpp b/test/SemaCXX/cxx98-compat-pedantic.cpp
new file mode 100644
index 000000000000..2ca0ae4d1ec8
--- /dev/null
+++ b/test/SemaCXX/cxx98-compat-pedantic.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Werror %s
+
+// -Wc++98-compat-pedantic warns on C++11 features which we accept without a
+// warning in C++98 mode.
+
+#line 32767 // ok
+#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}}
diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp
new file mode 100644
index 000000000000..6a3881cf4217
--- /dev/null
+++ b/test/SemaCXX/cxx98-compat.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s
+
+template<typename ...T> // expected-warning {{variadic templates are incompatible with C++98}}
+class Variadic1 {};
+
+template<template<typename> class ...T> // expected-warning {{variadic templates are incompatible with C++98}}
+class Variadic2 {};
+
+template<int ...I> // expected-warning {{variadic templates are incompatible with C++98}}
+class Variadic3 {};
+
+int alignas(8) with_alignas; // expected-warning {{'alignas' is incompatible with C++98}}
+int with_attribute [[ ]]; // expected-warning {{attributes are incompatible with C++98}}
+
+void Literals() {
+ (void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}}
+ (void)u"str"; // expected-warning {{unicode literals are incompatible with C++98}}
+ (void)U"str"; // expected-warning {{unicode literals are incompatible with C++98}}
+ (void)u'x'; // expected-warning {{unicode literals are incompatible with C++98}}
+ (void)U'x'; // expected-warning {{unicode literals are incompatible with C++98}}
+
+ (void)u8R"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
+ (void)uR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
+ (void)UR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
+ (void)R"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
+ (void)LR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}}
+}
+
+template<typename T> struct S {};
+S<::S<void> > s; // expected-warning {{'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98}}
diff --git a/test/SemaCXX/decl-init-ref.cpp b/test/SemaCXX/decl-init-ref.cpp
index 34c4578e9d6d..4c635c1a2447 100644
--- a/test/SemaCXX/decl-init-ref.cpp
+++ b/test/SemaCXX/decl-init-ref.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
struct A {};
diff --git a/test/SemaCXX/decltype-crash.cpp b/test/SemaCXX/decltype-crash.cpp
index f94ba453ffb4..50b3e49b78a5 100644
--- a/test/SemaCXX/decltype-crash.cpp
+++ b/test/SemaCXX/decltype-crash.cpp
@@ -3,5 +3,5 @@
int& a();
void f() {
- decltype(a()) c; // expected-error {{use of undeclared identifier 'decltype'}}
+ decltype(a()) c; // expected-warning {{'decltype' is a keyword in C++11}} expected-error {{use of undeclared identifier 'decltype'}}
}
diff --git a/test/SemaCXX/decltype-overloaded-functions.cpp b/test/SemaCXX/decltype-overloaded-functions.cpp
index f4aacd64ddbc..b0a43a999bb6 100644
--- a/test/SemaCXX/decltype-overloaded-functions.cpp
+++ b/test/SemaCXX/decltype-overloaded-functions.cpp
@@ -1,15 +1,15 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
-void f(); // expected-note{{candidate function}}
-void f(int); // expected-note{{candidate function}}
-decltype(f) a; // expected-error{{cannot resolve overloaded function 'f' from context}}
+void f(); // expected-note{{possible target for call}}
+void f(int); // expected-note{{possible target for call}}
+decltype(f) a; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{variable has incomplete type 'decltype(f())' (aka 'void')}}
template<typename T> struct S {
- decltype(T::f) * f; // expected-error{{cannot resolve overloaded function 'f' from context}}
+ decltype(T::f) * f; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{call to non-static member function without an object argument}}
};
struct K {
- void f(); // expected-note{{candidate function}}
- void f(int); // expected-note{{candidate function}}
+ void f(); // expected-note{{possible target for call}}
+ void f(int); // expected-note{{possible target for call}}
};
S<K> b; // expected-note{{in instantiation of template class 'S<K>' requested here}}
diff --git a/test/SemaCXX/decltype-pr4444.cpp b/test/SemaCXX/decltype-pr4444.cpp
index 456b22c5f7f2..2f95075067a4 100644
--- a/test/SemaCXX/decltype-pr4444.cpp
+++ b/test/SemaCXX/decltype-pr4444.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
template<typename T, T t>
struct TestStruct {
diff --git a/test/SemaCXX/decltype-pr4448.cpp b/test/SemaCXX/decltype-pr4448.cpp
index ead24ce0ca86..9d33ce7341a2 100644
--- a/test/SemaCXX/decltype-pr4448.cpp
+++ b/test/SemaCXX/decltype-pr4448.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
template< typename T, T t, decltype(t+2) v >
struct Convoluted {};
diff --git a/test/SemaCXX/decltype-this.cpp b/test/SemaCXX/decltype-this.cpp
index f9bf49973b5c..a13416f089dd 100644
--- a/test/SemaCXX/decltype-this.cpp
+++ b/test/SemaCXX/decltype-this.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
template<typename T, typename U> struct is_same {
static const bool value = false;
diff --git a/test/SemaCXX/decltype.cpp b/test/SemaCXX/decltype.cpp
index f61a92b71e1e..78fb8ef02078 100644
--- a/test/SemaCXX/decltype.cpp
+++ b/test/SemaCXX/decltype.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
// PR5290
int const f0();
diff --git a/test/SemaCXX/defaulted-ctor-loop.cpp b/test/SemaCXX/defaulted-ctor-loop.cpp
index 6a41972cf75a..6416336c6eed 100644
--- a/test/SemaCXX/defaulted-ctor-loop.cpp
+++ b/test/SemaCXX/defaulted-ctor-loop.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// WARNING: This test may recurse infinitely if failing.
diff --git a/test/SemaCXX/delete.cpp b/test/SemaCXX/delete.cpp
index 4567888a37b1..5824facc507b 100644
--- a/test/SemaCXX/delete.cpp
+++ b/test/SemaCXX/delete.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: cp %s %t
// RUN: %clang_cc1 -fixit -x c++ %t
-// RUN: FileCheck -input-file=%t %s
+// RUN: %clang_cc1 -E -o - %t | FileCheck %s
void f(int a[10][20]) {
// CHECK: delete[] a;
diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp
index 6a8965ceb578..4620a19d46fb 100644
--- a/test/SemaCXX/deleted-function.cpp
+++ b/test/SemaCXX/deleted-function.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
int i = delete; // expected-error {{only functions can have deleted definitions}}
diff --git a/test/SemaCXX/deleted-operator.cpp b/test/SemaCXX/deleted-operator.cpp
new file mode 100644
index 000000000000..e357401bf942
--- /dev/null
+++ b/test/SemaCXX/deleted-operator.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+struct PR10757 {
+ bool operator~() = delete; // expected-note {{explicitly deleted}}
+ bool operator==(const PR10757&) = delete; // expected-note {{explicitly deleted}}
+ operator float();
+};
+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}}
+}
diff --git a/test/SemaCXX/dependent-auto.cpp b/test/SemaCXX/dependent-auto.cpp
index 52b15eda7324..1be1566bb3b0 100644
--- a/test/SemaCXX/dependent-auto.cpp
+++ b/test/SemaCXX/dependent-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
template<typename T>
struct only {
diff --git a/test/SemaCXX/dependent-noexcept-unevaluated.cpp b/test/SemaCXX/dependent-noexcept-unevaluated.cpp
index 5bf6f9e96a12..8066b859f189 100644
--- a/test/SemaCXX/dependent-noexcept-unevaluated.cpp
+++ b/test/SemaCXX/dependent-noexcept-unevaluated.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s
template <class T>
T&&
diff --git a/test/SemaCXX/dependent-types.cpp b/test/SemaCXX/dependent-types.cpp
index 053e79bb6981..13ed72f7231e 100644
--- a/test/SemaCXX/dependent-types.cpp
+++ b/test/SemaCXX/dependent-types.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++11 %s
template<typename T> using U = int &;
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index ec0539b81901..14a0cda8df35 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
class A {
public:
~A();
diff --git a/test/SemaCXX/enum-bitfield.cpp b/test/SemaCXX/enum-bitfield.cpp
index a766116b1c3c..1a657408f8a6 100644
--- a/test/SemaCXX/enum-bitfield.cpp
+++ b/test/SemaCXX/enum-bitfield.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++0x -verify -triple x86_64-apple-darwin %s
+// RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++11 -verify -triple x86_64-apple-darwin %s
enum E {};
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index 73e7578ecb6e..35ba1b4017ae 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++0x -verify -triple x86_64-apple-darwin %s
+// RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++11 -verify -triple x86_64-apple-darwin %s
enum class E1 {
Val1 = 1L
diff --git a/test/SemaCXX/explicit.cpp b/test/SemaCXX/explicit.cpp
index 717ed1e3caf2..11b9672a8501 100644
--- a/test/SemaCXX/explicit.cpp
+++ b/test/SemaCXX/explicit.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
namespace Constructor {
struct A {
A(int);
@@ -36,4 +36,149 @@ namespace Conversion {
void f(A a, B b) {
b.f(a);
}
+
+ void testExplicit()
+ {
+ // Taken from 12.3.2p2
+ class Y { }; // expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y &' for 1st argument}} \
+ expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y &&' for 1st argument}} \
+ expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y &' for 1st argument}} \
+ expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \
+ expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
+ expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \
+ expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} \
+ expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
+ expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \
+ expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} \
+ expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
+ expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y &&' for 1st argument}} \
+ expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
+ struct Z {
+ explicit operator Y() const;
+ explicit operator int() const;
+ };
+
+ Z z;
+ // 13.3.1.4p1 & 8.5p16:
+ Y y2 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'Conversion::Y'}}
+ // FIXME: These are well-formed per C++0x 13.3.1.4p1 (see DR899).
+ Y y3 = (Y)z; // expected-error {{no matching conversion for C-style cast from 'Conversion::Z' to 'Conversion::Y''}}
+ Y y4 = Y(z); // expected-error {{no matching conversion for functional-style cast from 'Conversion::Z' to 'Conversion::Y'}}
+ Y y5 = static_cast<Y>(z); // expected-error {{no matching conversion for static_cast from 'Conversion::Z' to 'Conversion::Y'}}
+ // 13.3.1.5p1 & 8.5p16:
+ int i1 = (int)z;
+ int i2 = int(z);
+ int i3 = static_cast<int>(z);
+ int i4(z);
+ // 13.3.1.6p1 & 8.5.3p5:
+ const Y& y6 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'const Conversion::Y'}}
+ const int& y7(z);
+ }
+
+ void testBool() {
+ struct Bool {
+ operator bool();
+ };
+
+ struct NotBool {
+ explicit operator bool(); // expected-note {{conversion to integral type 'bool'}}
+ };
+ Bool b;
+ NotBool n;
+
+ (void) (1 + b);
+ (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'Conversion::NotBool')}}
+
+ // 5.3.1p9:
+ (void) (!b);
+ (void) (!n);
+
+ // 5.14p1:
+ (void) (b && true);
+ (void) (n && true);
+
+ // 5.15p1:
+ (void) (b || true);
+ (void) (n || true);
+
+ // 5.16p1:
+ (void) (b ? 0 : 1);
+ (void) (n ? 0: 1);
+
+ // 5.19p5:
+ // TODO: After constexpr has been implemented
+
+ // 6.4p4:
+ if (b) {}
+ if (n) {}
+
+ // 6.4.2p2:
+ switch (b) {} // expected-warning {{switch condition has boolean value}}
+ switch (n) {} // expected-error {{switch condition type 'Conversion::NotBool' requires explicit conversion to 'bool'}} \
+ expected-warning {{switch condition has boolean value}}
+
+ // 6.5.1:
+ while (b) {}
+ while (n) {}
+
+ // 6.5.2p1:
+ do {} while (b);
+ do {} while (n);
+
+ // 6.5.3:
+ for (;b;) {}
+ for (;n;) {}
+ }
+
+ void testNew()
+ {
+ // 5.3.4p6:
+ struct Int {
+ operator int();
+ };
+ struct NotInt {
+ explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}}
+ };
+
+ Int i;
+ NotInt ni;
+
+ new int[i];
+ new int[ni]; // expected-error {{array size expression of type 'Conversion::NotInt' requires explicit conversion to type 'int'}}
+ }
+
+ void testDelete()
+ {
+ // 5.3.5pp2:
+ struct Ptr {
+ operator int*();
+ };
+ struct NotPtr {
+ explicit operator int*();
+ };
+
+ Ptr p;
+ NotPtr np;
+
+ delete p;
+ delete np; // expected-error {{cannot delete expression of type 'Conversion::NotPtr'}}
+ }
+
+ void testFunctionPointer()
+ {
+ // 13.3.1.1.2p2:
+ using Func = void(*)(int);
+
+ struct FP {
+ operator Func();
+ };
+ struct NotFP {
+ explicit operator Func();
+ };
+
+ FP fp;
+ NotFP nfp;
+ fp(1);
+ nfp(1); // expected-error {{type 'Conversion::NotFP' does not provide a call operator}}
+ }
}
diff --git a/test/SemaCXX/expression-traits.cpp b/test/SemaCXX/expression-traits.cpp
index 4555192280f0..32b3ff91e95b 100644
--- a/test/SemaCXX/expression-traits.cpp
+++ b/test/SemaCXX/expression-traits.cpp
@@ -136,7 +136,7 @@ void conv_ptr_1()
void expr_6()
{
- // expr/6: If an expression initially has the type “reference to T”
+ // expr/6: If an expression initially has the type "reference to T"
// (8.3.2, 8.5.3), ... the expression is an lvalue.
int x = 0;
int& referenceToInt = x;
@@ -185,8 +185,8 @@ struct Class : BaseClass
template <class T>
struct NestedClassTemplate {};
- template <class T>
- static int& NestedFuncTemplate() { return variable; } // expected-note{{candidate function}}
+ template <class T> // expected-note{{possible target for call}}
+ static int& NestedFuncTemplate() { return variable; }
template <class T>
int& NestedMemfunTemplate() { return variable; }
@@ -234,13 +234,13 @@ struct Class : BaseClass
// doesn't come up in legal pure C++ programs). This language
// extension simply rejects them as requiring additional context
__is_lvalue_expr(::Class::NestedFuncTemplate); // qualified-id: template \
- // expected-error{{cannot resolve overloaded function 'NestedFuncTemplate' from context}}
+ // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
__is_lvalue_expr(::Class::NestedMemfunTemplate); // qualified-id: template \
- // expected-error{{a bound member function may only be called}}
+ // expected-error{{reference to non-static member function must be called}}
__is_lvalue_expr(::Class::operator+); // operator-function-id: template \
- // expected-error{{a bound member function may only be called}}
+ // expected-error{{reference to non-static member function must be called}}
//ASSERT_RVALUE(::Class::operator*); // operator-function-id: member function
}
@@ -310,9 +310,9 @@ void expr_sub_1(int* pointer)
{
// expr.sub/1 A postfix expression followed by an expression in
// square brackets is a postfix expression. One of the expressions
- // shall have the type “pointer to T” and the other shall have
+ // shall have the type "pointer to T" and the other shall have
// enumeration or integral type. The result is an lvalue of type
- // “T.”
+ // "T."
ASSERT_LVALUE(pointer[1]);
// The expression E1[E2] is identical (by definition) to *((E1)+(E2)).
@@ -348,32 +348,32 @@ void expr_ref_4()
{
// Applies to expressions of the form E1.E2
- // If E2 is declared to have type “reference to T”, then E1.E2 is
+ // If E2 is declared to have type "reference to T", then E1.E2 is
// an lvalue;.... Otherwise, one of the following rules applies.
ASSERT_LVALUE(Class().staticReferenceDataMember);
ASSERT_LVALUE(Class().referenceDataMember);
- // — If E2 is a static data member, and the type of E2 is T, then
+ // - If E2 is a static data member, and the type of E2 is T, then
// E1.E2 is an lvalue; ...
ASSERT_LVALUE(Class().staticNonreferenceDataMember);
ASSERT_LVALUE(Class().staticReferenceDataMember);
- // — If E2 is a non-static data member, ... If E1 is an lvalue,
+ // - If E2 is a non-static data member, ... If E1 is an lvalue,
// then E1.E2 is an lvalue...
Class lvalue;
ASSERT_LVALUE(lvalue.dataMember);
ASSERT_RVALUE(Class().dataMember);
- // — If E1.E2 refers to a static member function, ... then E1.E2
+ // - If E1.E2 refers to a static member function, ... then E1.E2
// is an lvalue
ASSERT_LVALUE(Class().StaticMemberFunction);
- // — Otherwise, if E1.E2 refers to a non-static member function,
+ // - Otherwise, if E1.E2 refers to a non-static member function,
// then E1.E2 is not an lvalue.
//ASSERT_RVALUE(Class().NonstaticMemberFunction);
- // — If E2 is a member enumerator, and the type of E2 is T, the
+ // - If E2 is a member enumerator, and the type of E2 is T, the
// expression E1.E2 is not an lvalue. The type of E1.E2 is T.
ASSERT_RVALUE(Class().Enumerator);
ASSERT_RVALUE(lvalue.Enumerator);
@@ -404,8 +404,8 @@ void expr_dynamic_cast_2()
void expr_dynamic_cast_5()
{
- // expr.dynamic.cast/5: If T is “reference to cv1 B” and v has type
- // “cv2 D” such that B is a base class of D, the result is an
+ // expr.dynamic.cast/5: If T is "reference to cv1 B" and v has type
+ // "cv2 D" such that B is a base class of D, the result is an
// lvalue for the unique B sub-object of the D object referred
// to by v.
typedef BaseClass B;
@@ -416,13 +416,13 @@ void expr_dynamic_cast_5()
// expr.dynamic.cast/8: The run-time check logically executes as follows:
//
-// — If, in the most derived object pointed (referred) to by v, v
+// - If, in the most derived object pointed (referred) to by v, v
// points (refers) to a public base class subobject of a T object, and
// if only one object of type T is derived from the sub-object pointed
// (referred) to by v, the result is a pointer (an lvalue referring)
// to that T object.
//
-// — Otherwise, if v points (refers) to a public base class sub-object
+// - Otherwise, if v points (refers) to a public base class sub-object
// of the most derived object, and the type of the most derived object
// has a base class, of type T, that is unambiguous and public, the
// result is a pointer (an lvalue referring) to the T sub-object of
@@ -525,7 +525,7 @@ void expr_cond(bool cond)
// conversions are performed on the second and third operands, and one
// of the following shall hold:
//
- // — The second or the third operand (but not both) is a
+ // - The second or the third operand (but not both) is a
// throw-expression (15.1); the result is of the type of the other and
// is an rvalue.
@@ -535,7 +535,7 @@ void expr_cond(bool cond)
ASSERT_RVALUE(cond ? throw 1 : classLvalue);
ASSERT_RVALUE(cond ? classLvalue : throw 1);
- // — Both the second and the third operands have type void; the result
+ // - Both the second and the third operands have type void; the result
// is of type void and is an rvalue. [Note: this includes the case
// where both operands are throw-expressions. ]
ASSERT_RVALUE(cond ? (void)1 : (void)0);
diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp
index 8a294face380..355833e693fa 100644
--- a/test/SemaCXX/expressions.cpp
+++ b/test/SemaCXX/expressions.cpp
@@ -34,7 +34,9 @@ namespace test1 {
}
int test2(int x) {
- return x && 4; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ return x && 4; // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
return x && sizeof(int) == 4; // no warning, RHS is logical op.
return x && true;
@@ -42,38 +44,69 @@ int test2(int x) {
return x || true;
return x || false;
- return x && (unsigned)0; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ return x && (unsigned)0; // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
- return x || (unsigned)1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
+ return x || (unsigned)1; // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
- return x || 0; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
- return x || 1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
- return x || -1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
- return x || 5; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
- return x && 0; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
- return x && 1; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
- return x && -1; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
- return x && 5; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
- return x || (0); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
- return x || (1); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
- return x || (-1); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
- return x || (5); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}}
- return x && (0); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
- return x && (1); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
- return x && (-1); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
- return x && (5); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ return x || 0; // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
+ return x || 1; // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
+ return x || -1; // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
+ return x || 5; // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
+ return x && 0; // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
+ return x && 1; // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
+ return x && -1; // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
+ return x && 5; // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
+ return x || (0); // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
+ return x || (1); // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
+ return x || (-1); // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
+ return x || (5); // expected-warning {{use of logical '||' with constant operand}} \
+ // expected-note {{use '|' for a bitwise operation}}
+ return x && (0); // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
+ return x && (1); // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
+ return x && (-1); // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
+ return x && (5); // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
}
template<unsigned int A, unsigned int B> struct S
{
enum {
e1 = A && B,
- e2 = A && 7 // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ e2 = A && 7 // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
};
int foo() {
int x = A && B;
- int y = B && 3; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}}
+ int y = B && 3; // expected-warning {{use of logical '&&' with constant operand}} \
+ // expected-note {{use '&' for a bitwise operation}} \
+ // expected-note {{remove constant to silence this warning}}
return x + y;
}
diff --git a/test/SemaCXX/for-range-examples.cpp b/test/SemaCXX/for-range-examples.cpp
index 810f1de441a1..b994e8c10bd6 100644
--- a/test/SemaCXX/for-range-examples.cpp
+++ b/test/SemaCXX/for-range-examples.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
namespace value_range_detail {
template<typename T>
diff --git a/test/SemaCXX/for-range-no-std.cpp b/test/SemaCXX/for-range-no-std.cpp
index 8cc71e5111a2..dae41f1bb296 100644
--- a/test/SemaCXX/for-range-no-std.cpp
+++ b/test/SemaCXX/for-range-no-std.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++0x-extensions
struct S {
int *begin();
diff --git a/test/SemaCXX/for-range-unused.cpp b/test/SemaCXX/for-range-unused.cpp
index 7b7d84d3f9c8..ce6b379cc192 100644
--- a/test/SemaCXX/for-range-unused.cpp
+++ b/test/SemaCXX/for-range-unused.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x -Wunused
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wunused
// PR9968: We used to warn that __range is unused in a dependent for-range.
diff --git a/test/SemaCXX/function-overload-typo-crash.cpp b/test/SemaCXX/function-overload-typo-crash.cpp
index 0fea312a97f2..8c5cec8af3a9 100644
--- a/test/SemaCXX/function-overload-typo-crash.cpp
+++ b/test/SemaCXX/function-overload-typo-crash.cpp
@@ -1,12 +1,28 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// PR10283
-void min();
+void min(); //expected-note {{'min' declared here}}
void min(int);
-template <typename T> void max(T);
+template <typename T> void max(T); //expected-note {{'max' declared here}}
void f() {
fin(); //expected-error {{use of undeclared identifier 'fin'; did you mean 'min'}}
fax(0); //expected-error {{use of undeclared identifier 'fax'; did you mean 'max'}}
}
+
+template <typename T> void somefunc(T*, T*); //expected-note {{'somefunc' declared here}}
+template <typename T> void somefunc(const T[]); //expected-note {{'somefunc' declared here}}
+template <typename T1, typename T2> void somefunc(T1*, T2*); //expected-note {{'somefunc' declared here}}
+template <typename T1, typename T2> void somefunc(T1*, const T2[]); //expected-note 2 {{'somefunc' declared here}}
+
+void c() {
+ int *i = 0, *j = 0;
+ const int x[] = {1, 2, 3};
+ long *l = 0;
+ somefun(i, j); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}}
+ somefun(x); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}}
+ somefun(i, l); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}}
+ somefun(l, x); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}}
+ somefun(i, x); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}}
+}
diff --git a/test/SemaCXX/function-redecl.cpp b/test/SemaCXX/function-redecl.cpp
index b15d86616585..0d9ecf334e6a 100644
--- a/test/SemaCXX/function-redecl.cpp
+++ b/test/SemaCXX/function-redecl.cpp
@@ -24,3 +24,74 @@ namespace N {
}
}
}
+
+class A {
+ void typocorrection(); // expected-note {{'typocorrection' declared here}}
+};
+
+void A::Notypocorrection() { // expected-error {{out-of-line definition of 'Notypocorrection' does not match any declaration in 'A'; did you mean 'typocorrection'}}
+}
+
+
+namespace test0 {
+ void dummy() {
+ void Bar(); // expected-note {{'Bar' declared here}}
+ class A {
+ friend void bar(); // expected-error {{no matching function 'bar' found in local scope; did you mean 'Bar'}}
+ };
+ }
+}
+
+
+class B {
+ void typocorrection(const int); // expected-note {{'typocorrection' declared here}}
+ void typocorrection(double);
+};
+
+void B::Notypocorrection(int) { // expected-error {{out-of-line definition of 'Notypocorrection' does not match any declaration in 'B'; did you mean 'typocorrection'}}
+}
+
+struct X { int f(); };
+struct Y : public X {};
+int Y::f() { return 3; } // expected-error {{out-of-line definition of 'f' does not match any declaration in 'Y'}}
+
+namespace test1 {
+struct Foo {
+ class Inner { };
+};
+}
+
+class Bar {
+ void f(test1::Foo::Inner foo) const; // expected-note {{member declaration does not match because it is const qualified}}
+};
+
+using test1::Foo;
+
+void Bar::f(Foo::Inner foo) { // expected-error {{out-of-line definition of 'f' does not match any declaration in 'Bar'}}
+ (void)foo;
+}
+
+class Crash {
+ public:
+ 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'}}
+// ...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'}}
+
+class TestConst {
+ public:
+ int getit() const; // expected-note {{member declaration does not match because it is const qualified}}
+ void setit(int); // expected-note {{member declaration does not match because it is not const qualified}}
+};
+
+int TestConst::getit() { // expected-error {{out-of-line definition of 'getit' does not match any declaration in 'TestConst'}}
+ return 1;
+}
+
+void TestConst::setit(int) const { // expected-error {{out-of-line definition of 'setit' does not match any declaration in 'TestConst'}}
+}
+
+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'}}
diff --git a/test/SemaCXX/generalized-initializers.cpp b/test/SemaCXX/generalized-initializers.cpp
index 6e2bee7e301d..a1891c9c322e 100644
--- a/test/SemaCXX/generalized-initializers.cpp
+++ b/test/SemaCXX/generalized-initializers.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
// XFAIL: *
template <typename T, typename U>
@@ -40,25 +40,9 @@ namespace std {
namespace integral {
- void initialization() {
- { const int a{}; static_assert(a == 0, ""); }
- { const int a = {}; static_assert(a == 0, ""); }
- { const int a{1}; static_assert(a == 1, ""); }
- { const int a = {1}; static_assert(a == 1, ""); }
- { const int a{1, 2}; } // expected-error {{excess elements}}
- { const int a = {1, 2}; } // expected-error {{excess elements}}
- { const short a{100000}; } // expected-error {{narrowing conversion}}
- { const short a = {100000}; } // expected-error {{narrowing conversion}}
- }
-
int function_call() {
void takes_int(int);
takes_int({1});
-
- int ar[10];
- (void) ar[{1}]; // expected-error {{initializer list is illegal with the built-in index operator}}
-
- return {1};
}
void inline_init() {
@@ -76,11 +60,6 @@ namespace integral {
for (int i : {1, 2, 3, 4}) {}
}
- struct A {
- int i;
- A() : i{1} {}
- };
-
}
namespace objects {
diff --git a/test/SemaCXX/generic-selection.cpp b/test/SemaCXX/generic-selection.cpp
index b171fce540d8..c0a5d89fff67 100644
--- a/test/SemaCXX/generic-selection.cpp
+++ b/test/SemaCXX/generic-selection.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
template <typename T, typename U = void*>
struct A {
diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp
index 186e32126a39..4d02ca8f174e 100644
--- a/test/SemaCXX/i-c-e-cxx.cpp
+++ b/test/SemaCXX/i-c-e-cxx.cpp
@@ -54,4 +54,10 @@ struct A {
int foo() { return A::B; }
}
+// PR11040
+const int x = 10;
+int* y = reinterpret_cast<const char&>(x); // expected-error {{cannot initialize}}
+// This isn't an integral constant expression, but make sure it folds anyway.
+struct PR8836 { char _; long long a; };
+int PR8836test[(__typeof(sizeof(int)))&reinterpret_cast<const volatile char&>((((PR8836*)0)->a))];
diff --git a/test/SemaCXX/implicit-exception-spec.cpp b/test/SemaCXX/implicit-exception-spec.cpp
index 81babc043ff7..559c3013f7e9 100644
--- a/test/SemaCXX/implicit-exception-spec.cpp
+++ b/test/SemaCXX/implicit-exception-spec.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++0x -Wall %s
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 -Wall %s
template<bool b> struct ExceptionIf { static int f(); };
template<> struct ExceptionIf<false> { typedef int f; };
diff --git a/test/SemaCXX/issue547.cpp b/test/SemaCXX/issue547.cpp
index 03c5b7c978aa..5b82dc6b145e 100644
--- a/test/SemaCXX/issue547.cpp
+++ b/test/SemaCXX/issue547.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
template<typename T>
struct classify_function {
diff --git a/test/SemaCXX/libstdcxx_is_pod_hack.cpp b/test/SemaCXX/libstdcxx_is_pod_hack.cpp
index 3581c796ce91..3ac233627ccb 100644
--- a/test/SemaCXX/libstdcxx_is_pod_hack.cpp
+++ b/test/SemaCXX/libstdcxx_is_pod_hack.cpp
@@ -27,3 +27,7 @@ struct test_is_signed {
};
bool check_signed = test_is_signed::__is_signed;
+
+#if __has_feature(is_pod)
+# error __is_pod won't work now anyway
+#endif
diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp
index b5a10a795ebc..cb7e32c05d88 100644
--- a/test/SemaCXX/linkage-spec.cpp
+++ b/test/SemaCXX/linkage-spec.cpp
@@ -89,3 +89,16 @@ extern "C++" using N::value;
// PR7076
extern "C" const char *Version_string = "2.9";
+
+namespace PR9162 {
+ extern "C" {
+ typedef struct _ArtsSink ArtsSink;
+ struct _ArtsSink {
+ int sink;
+ };
+ }
+ int arts_sink_get_type()
+ {
+ return sizeof(ArtsSink);
+ }
+}
diff --git a/test/SemaCXX/literal-operators.cpp b/test/SemaCXX/literal-operators.cpp
index ec585a61da9f..06ef49fc0ae1 100644
--- a/test/SemaCXX/literal-operators.cpp
+++ b/test/SemaCXX/literal-operators.cpp
@@ -1,41 +1,41 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
#include <stddef.h>
struct tag {
- void operator "" tag_bad (const char *); // expected-error {{literal operator 'operator "" tag_bad' must be in a namespace or global scope}}
- friend void operator "" tag_good (const char *);
+ void operator "" _tag_bad (const char *); // expected-error {{literal operator 'operator "" _tag_bad' must be in a namespace or global scope}}
+ friend void operator "" _tag_good (const char *);
};
-namespace ns { void operator "" ns_good (const char *); }
+namespace ns { void operator "" _ns_good (const char *); }
// Check extern "C++" declarations
-extern "C++" void operator "" extern_good (const char *);
-extern "C++" { void operator "" extern_good (const char *); }
+extern "C++" void operator "" _extern_good (const char *);
+extern "C++" { void operator "" _extern_good (const char *); }
-void fn () { void operator "" fn_bad (const char *); } // expected-error {{literal operator 'operator "" fn_bad' must be in a namespace or global scope}}
+void fn () { void operator "" _fn_bad (const char *); } // expected-error {{literal operator 'operator "" _fn_bad' must be in a namespace or global scope}}
// One-param declarations (const char * was already checked)
-void operator "" good (char);
-void operator "" good (wchar_t);
-void operator "" good (char16_t);
-void operator "" good (char32_t);
-void operator "" good (unsigned long long);
-void operator "" good (long double);
+void operator "" _good (char);
+void operator "" _good (wchar_t);
+void operator "" _good (char16_t);
+void operator "" _good (char32_t);
+void operator "" _good (unsigned long long);
+void operator "" _good (long double);
// Two-param declarations
-void operator "" good (const char *, size_t);
-void operator "" good (const wchar_t *, size_t);
-void operator "" good (const char16_t *, size_t);
-void operator "" good (const char32_t *, size_t);
+void operator "" _good (const char *, size_t);
+void operator "" _good (const wchar_t *, size_t);
+void operator "" _good (const char16_t *, size_t);
+void operator "" _good (const char32_t *, size_t);
// Check typedef and array equivalences
-void operator "" good (const char[]);
+void operator "" _good (const char[]);
typedef const char c;
-void operator "" good (c*);
+void operator "" _good (c*);
// Check extra cv-qualifiers
-void operator "" cv_good (volatile const char *, const size_t);
+void operator "" _cv_good (volatile const char *, const size_t);
// Template delcaration (not implemented yet)
// template <char...> void operator "" good ();
diff --git a/test/SemaCXX/literal-type.cpp b/test/SemaCXX/literal-type.cpp
index 6a61823adb28..60bfcf00cf0b 100644
--- a/test/SemaCXX/literal-type.cpp
+++ b/test/SemaCXX/literal-type.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
static_assert(__is_literal(int), "fail");
static_assert(__is_literal_type(int), "fail"); // alternate spelling for GCC
diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp
index 981bae7c770b..2e3fd73d7ff5 100644
--- a/test/SemaCXX/member-expr.cpp
+++ b/test/SemaCXX/member-expr.cpp
@@ -28,7 +28,7 @@ struct B {
A *f0();
};
int f0(B *b) {
- return b->f0->f0; // expected-error{{perhaps you meant to call it with no arguments}}
+ return b->f0->f0; // expected-error{{did you mean to call it with no arguments}}
}
int i;
@@ -118,32 +118,32 @@ namespace rdar8231724 {
namespace PR9025 {
struct S { int x; };
- S fun();
- int fun(int i);
+ S fun(); // expected-note{{possible target for call}}
+ int fun(int i); // expected-note{{possible target for call}}
int g() {
- return fun.x; // expected-error{{base of member reference is an overloaded function; perhaps you meant to call it with no arguments?}}
+ return fun.x; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}}
}
- S fun2();
- S fun2(int i);
+ S fun2(); // expected-note{{possible target for call}}
+ S fun2(int i); // expected-note{{possible target for call}}
int g2() {
- return fun2.x; // expected-error{{base of member reference is an overloaded function; perhaps you meant to call it with no arguments?}}
+ return fun2.x; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}}
}
- S fun3(int i=0);
- int fun3(int i, int j);
+ S fun3(int i=0); // expected-note{{possible target for call}}
+ int fun3(int i, int j); // expected-note{{possible target for call}}
int g3() {
- return fun3.x; // expected-error{{base of member reference is an overloaded function; perhaps you meant to call it with no arguments?}}
+ return fun3.x; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}}
}
- template <typename T> S fun4();
+ template <typename T> S fun4(); // expected-note{{possible target for call}}
int g4() {
- return fun4.x; // expected-error{{base of member reference is a function; perhaps you meant to call it?}}
+ return fun4.x; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
}
- S fun5(int i); // expected-note{{possibly valid overload here}}
- S fun5(float f); // expected-note{{possibly valid overload here}}
+ S fun5(int i); // expected-note{{possible target for call}}
+ S fun5(float f); // expected-note{{possible target for call}}
int g5() {
- return fun5.x; // expected-error{{base of member reference is an overloaded function; perhaps you meant to call it?}}
+ return fun5.x; // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
}
}
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index 7ca1f0e4513e..819c8d13db89 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++0x -Wall %s
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 -Wall %s
struct Bitfield {
int n : 3 = 7; // expected-error {{bitfield member cannot have an in-class initializer}}
@@ -52,3 +52,21 @@ struct CheckExcSpecFail {
struct TypedefInit {
typedef int A = 0; // expected-error {{illegal initializer}}
};
+
+// PR10578 / <rdar://problem/9877267>
+namespace PR10578 {
+ template<typename T>
+ struct X {
+ X() {
+ T* x = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+ }
+ };
+
+ struct Y : X<int> {
+ Y();
+ };
+
+ Y::Y() try { // expected-note{{in instantiation of member function 'PR10578::X<int>::X' requested here}}
+ } catch(...) {
+ }
+}
diff --git a/test/SemaCXX/microsoft-cxx0x.cpp b/test/SemaCXX/microsoft-cxx0x.cpp
new file mode 100644
index 000000000000..3f78eda79cd5
--- /dev/null
+++ b/test/SemaCXX/microsoft-cxx0x.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wc++0x-narrowing -Wmicrosoft -verify -fms-extensions -std=c++11
+
+
+struct A {
+ unsigned int a;
+};
+int b = 3;
+A var = { b }; // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+
+
diff --git a/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp b/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
index fd0c976bdd78..76ceea1d4d5b 100644
--- a/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
+++ b/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
@@ -1,8 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++0x-extensions %s
-namespace fizbin { class Foobar; } // expected-note{{'fizbin::Foobar' declared here}}
-Foobar *my_bar = new Foobar; // expected-error{{unknown type name 'Foobar'; did you mean 'fizbin::Foobar'?}} \
- // expected-error{{expected a type}}
+namespace fizbin { class Foobar {}; } // expected-note 2 {{'fizbin::Foobar' declared here}} \
+ // expected-note {{'Foobar' declared here}}
+Foobar *my_bar // expected-error{{unknown type name 'Foobar'; did you mean 'fizbin::Foobar'?}}
+ = new Foobar; // expected-error{{unknown type name 'Foobar'; did you mean 'fizbin::Foobar'?}}
+fizbin::Foobar *my_foo = new fizbin::FooBar; // expected-error{{unknown type name 'FooBar'; did you mean 'Foobar'?}}
namespace barstool { int toFoobar() { return 1; } } // expected-note 3 {{'barstool::toFoobar' declared here}}
int Double(int x) { return x + x; }
@@ -62,11 +64,13 @@ void f() {
// Test case from http://llvm.org/bugs/show_bug.cgi?id=10318
namespace llvm {
- template <typename T> class GraphWriter {}; // expected-note{{'llvm::GraphWriter' declared here}}
+ template <typename T> class GraphWriter {}; // expected-note {{'llvm::GraphWriter' declared here}} \
+ // expected-note {{'GraphWriter' declared here}}
}
struct S {};
void bar() {
GraphWriter<S> x; //expected-error{{no template named 'GraphWriter'; did you mean 'llvm::GraphWriter'?}}
-
+ (void)new llvm::GraphWriter; // expected-error {{expected a type}}
+ (void)new llvm::Graphwriter<S>; // expected-error {{no template named 'Graphwriter' in namespace 'llvm'; did you mean 'GraphWriter'?}}
}
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index ee6ca8857374..e13030cc38a8 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -27,10 +27,10 @@ int A::C::cx = 17;
static int A::C::cx2 = 17; // expected-error{{'static' can}}
class C2 {
- void m(); // expected-note{{member declaration nearly matches}}
+ void m(); // expected-note{{member declaration does not match because it is not const qualified}}
- void f(const int& parm); // expected-note{{member declaration nearly matches}}
- void f(int) const; // expected-note{{member declaration nearly matches}}
+ void f(const int& parm); // expected-note{{type of 1st parameter of member declaration does not match definition ('const int &' vs 'int')}}
+ void f(int) const; // expected-note{{member declaration does not match because it is const qualified}}
void f(float);
int x;
@@ -121,7 +121,7 @@ namespace E {
class Operators {
- Operators operator+(const Operators&) const; // expected-note{{member declaration nearly matches}}
+ Operators operator+(const Operators&) const; // expected-note{{member declaration does not match because it is const qualified}}
operator bool();
};
@@ -140,7 +140,7 @@ Operators::operator bool() {
}
namespace A {
- void g(int&); // expected-note{{member declaration nearly matches}}
+ 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'}}
diff --git a/test/SemaCXX/new-array-size-conv.cpp b/test/SemaCXX/new-array-size-conv.cpp
index 80219a906209..e8bb67955f97 100644
--- a/test/SemaCXX/new-array-size-conv.cpp
+++ b/test/SemaCXX/new-array-size-conv.cpp
@@ -19,8 +19,8 @@ struct IndirectValueInt : ValueInt { };
struct TwoValueInts : ValueInt, IndirectValueInt { };
void test() {
- (void)new int[ValueInt(10)]; // expected-warning{{implicit conversion from array size expression of type 'ValueInt' to integral type 'int' is a C++0x extension}}
- (void)new int[ValueEnum()]; // expected-warning{{implicit conversion from array size expression of type 'ValueEnum' to enumeration type 'E' is a C++0x extension}}
+ (void)new int[ValueInt(10)]; // expected-warning{{implicit conversion from array size expression of type 'ValueInt' to integral type 'int' is a C++11 extension}}
+ (void)new int[ValueEnum()]; // expected-warning{{implicit conversion from array size expression of type 'ValueEnum' to enumeration type 'E' is a C++11 extension}}
(void)new int[ValueBoth()]; // expected-error{{ambiguous conversion of array size expression of type 'ValueBoth' to an integral or enumeration type}}
(void)new int[TwoValueInts()]; // expected-error{{ambiguous conversion of array size expression of type 'TwoValueInts' to an integral or enumeration type}}
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index efdfa0f066db..748ce7770097 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -397,3 +397,22 @@ namespace ArrayNewNeedsDtor {
return new B[5]; // expected-note {{implicit default destructor for 'ArrayNewNeedsDtor::B' first required here}}
}
}
+
+namespace DeleteIncompleteClass {
+ struct A; // expected-note {{forward declaration}}
+ extern A x;
+ void f() { delete x; } // expected-error {{deleting incomplete class type}}
+}
+
+namespace DeleteIncompleteClassPointerError {
+ struct A; // expected-note {{forward declaration}}
+ void f(A *x) { 1+delete x; } // expected-warning {{deleting pointer to incomplete type}} \
+ // expected-error {{invalid operands to binary expression}}
+}
+
+namespace PR10504 {
+ struct A {
+ virtual void foo() = 0;
+ };
+ void f(A *x) { delete x; } // expected-warning {{delete called on 'PR10504::A' that is abstract but has non-virtual destructor}}
+}
diff --git a/test/SemaCXX/null_in_arithmetic_ops.cpp b/test/SemaCXX/null_in_arithmetic_ops.cpp
index fab6f10ab785..24590ce633f2 100644
--- a/test/SemaCXX/null_in_arithmetic_ops.cpp
+++ b/test/SemaCXX/null_in_arithmetic_ops.cpp
@@ -64,12 +64,12 @@ void f() {
a |= NULL; // expected-warning{{use of NULL in arithmetic operation}}
a ^= NULL; // expected-warning{{use of NULL in arithmetic operation}}
- b = a < NULL || NULL < a; // expected-warning 2{{use of NULL in arithmetic operation}}
- b = a > NULL || NULL > a; // expected-warning 2{{use of NULL in arithmetic operation}}
- b = a <= NULL || NULL <= a; // expected-warning 2{{use of NULL in arithmetic operation}}
- b = a >= NULL || NULL >= a; // expected-warning 2{{use of NULL in arithmetic operation}}
- b = a == NULL || NULL == a; // expected-warning 2{{use of NULL in arithmetic operation}}
- b = a != NULL || NULL != a; // expected-warning 2{{use of NULL in arithmetic operation}}
+ b = a < NULL || a > NULL; // expected-warning 2{{comparison between NULL and non-pointer ('int' and NULL)}}
+ b = NULL < a || NULL > a; // expected-warning 2{{comparison between NULL and non-pointer (NULL and 'int')}}
+ b = a <= NULL || a >= NULL; // expected-warning 2{{comparison between NULL and non-pointer ('int' and NULL)}}
+ b = NULL <= a || NULL >= a; // expected-warning 2{{comparison between NULL and non-pointer (NULL and 'int')}}
+ b = a == NULL || a != NULL; // expected-warning 2{{comparison between NULL and non-pointer ('int' and NULL)}}
+ b = NULL == a || NULL != a; // expected-warning 2{{comparison between NULL and non-pointer (NULL and 'int')}}
b = &a < NULL || NULL < &a || &a > NULL || NULL > &a;
b = &a <= NULL || NULL <= &a || &a >= NULL || NULL >= &a;
@@ -82,7 +82,7 @@ void f() {
b = NULL <= NULL || NULL >= NULL;
b = NULL == NULL || NULL != NULL;
- b = ((NULL)) != a; // expected-warning{{use of NULL in arithmetic operation}}
+ b = ((NULL)) != a; // expected-warning{{comparison between NULL and non-pointer (NULL and 'int')}}
// Check that even non-standard pointers don't warn.
b = c == NULL || NULL == c || c != NULL || NULL != c;
diff --git a/test/SemaCXX/nullptr.cpp b/test/SemaCXX/nullptr.cpp
index d69af588a7d0..6f660366e998 100644
--- a/test/SemaCXX/nullptr.cpp
+++ b/test/SemaCXX/nullptr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++0x -ffreestanding %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -ffreestanding %s
#include <stdint.h>
typedef decltype(nullptr) nullptr_t;
diff --git a/test/SemaCXX/nullptr_in_arithmetic_ops.cpp b/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
index e839ed116f8d..9671353907c7 100644
--- a/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
+++ b/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fblocks -std=c++0x -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fblocks -std=c++11 -verify %s
void foo() {
int a;
diff --git a/test/SemaCXX/out-of-line-def-mismatch.cpp b/test/SemaCXX/out-of-line-def-mismatch.cpp
new file mode 100644
index 000000000000..6ade5b802b65
--- /dev/null
+++ b/test/SemaCXX/out-of-line-def-mismatch.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
+
+namespace N2 {
+ struct S1;
+
+ namespace N1 {
+ class C1 {};
+
+ struct S2 {
+ void func(S1*); // expected-note {{type of 1st parameter of member declaration does not match definition ('N2::S1 *' vs 'N2::N1::S1 *')}}
+ void func(C1&, unsigned, const S1*); // expected-note {{type of 3rd parameter of member declaration does not match definition ('const N2::S1 *' vs 'const N2::N1::S1 *')}}
+ void func(const S1*, unsigned); //expected-note {{type of 1st parameter of member declaration does not match definition ('const N2::S1 *' vs 'N2::N1::S1')}}
+ void func(unsigned, const S1*); // expected-note {{type of 1st parameter of member declaration does not match definition ('unsigned int' vs 'unsigned int *')}}
+ };
+
+ struct S1 {};
+ }
+}
+
+void N2::N1::S2::func(S1*) {} // expected-error {{out-of-line definition of 'func' does not match any declaration in 'N2::N1::S2'}}
+void N2::N1::S2::func(C1&, unsigned, const S1*) {} // expected-error {{out-of-line definition of 'func' does not match any declaration in 'N2::N1::S2'}}
+void N2::N1::S2::func(S1*, double) {} // expected-error {{out-of-line definition of 'func' does not match any declaration in 'N2::N1::S2'}}
+void N2::N1::S2::func(S1, unsigned) {} // expected-error {{out-of-line definition of 'func' does not match any declaration in 'N2::N1::S2'}}
+void N2::N1::S2::func(unsigned*, S1*) {} // expected-error {{out-of-line definition of 'func' does not match any declaration in 'N2::N1::S2'}}
diff --git a/test/SemaCXX/overload-0x.cpp b/test/SemaCXX/overload-0x.cpp
new file mode 100644
index 000000000000..677d16a32c12
--- /dev/null
+++ b/test/SemaCXX/overload-0x.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+namespace test0 {
+ struct A { // expected-note {{candidate function (the implicit copy assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}} expected-note {{candidate function (the implicit move assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
+ A &operator=(void*); // expected-note {{candidate function not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
+ };
+
+ void test(const A &a) {
+ a = "help"; // expected-error {{no viable overloaded '='}}
+ }
+}
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 9cc48993fde9..00f6a9460a7a 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -525,3 +525,12 @@ namespace PR9507 {
f(n); // expected-error{{call to 'f' is ambiguous}}
}
}
+
+namespace rdar9803316 {
+ void foo(float);
+ int &foo(int);
+
+ void bar() {
+ int &ir = (&foo)(0);
+ }
+}
diff --git a/test/SemaCXX/overloaded-builtin-operators-0x.cpp b/test/SemaCXX/overloaded-builtin-operators-0x.cpp
index 32f199529064..6a5a162af679 100644
--- a/test/SemaCXX/overloaded-builtin-operators-0x.cpp
+++ b/test/SemaCXX/overloaded-builtin-operators-0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -std=c++0x -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -std=c++11 -verify %s
template <class T>
struct X
diff --git a/test/SemaCXX/overloaded-name.cpp b/test/SemaCXX/overloaded-name.cpp
index 73f12a902723..a5ec51ced23d 100644
--- a/test/SemaCXX/overloaded-name.cpp
+++ b/test/SemaCXX/overloaded-name.cpp
@@ -1,15 +1,15 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-int ovl(int); // expected-note 3{{candidate function}}
-float ovl(float); // expected-note 3{{candidate function}}
+int ovl(int); // expected-note 3{{possible target for call}}
+float ovl(float); // expected-note 3{{possible target for call}}
-template<typename T> T ovl(T); // expected-note 3{{candidate function}}
+template<typename T> T ovl(T); // expected-note 3{{possible target for call}}
void test(bool b) {
- (void)((void)0, ovl); // expected-error{{cannot resolve overloaded function 'ovl' from context}}
+ (void)((void)0, ovl); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
// PR7863
- (void)(b? ovl : &ovl); // expected-error{{cannot resolve overloaded function 'ovl' from context}}
- (void)(b? ovl<float> : &ovl); // expected-error{{cannot resolve overloaded function 'ovl' from context}}
+ (void)(b? ovl : &ovl); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
+ (void)(b? ovl<float> : &ovl); // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
(void)(b? ovl<float> : ovl<float>);
}
@@ -21,10 +21,11 @@ namespace rdar9623945 {
public:
const char* text(void);
void g(void) {
+ // FIXME: why 2x?
f(text());
- f(text); // expected-error{{a bound member function may only be called}}
+ f(text); // expected-error 2{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
f(text());
- f(text); // expected-error{{a bound member function may only be called}}
+ f(text); // expected-error 2{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
}
};
}
diff --git a/test/SemaCXX/overloaded-operator-decl.cpp b/test/SemaCXX/overloaded-operator-decl.cpp
index 5f8655cee70c..4519a2d1f9ad 100644
--- a/test/SemaCXX/overloaded-operator-decl.cpp
+++ b/test/SemaCXX/overloaded-operator-decl.cpp
@@ -43,3 +43,8 @@ namespace PR6238 {
void operator()();
} plus;
}
+
+struct PR10839 {
+ operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}}
+ int operator+; // expected-error{{'operator+' cannot be the name of a variable or data member}}
+};
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 462d0234f39f..1e4a3b7514ba 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -36,7 +36,7 @@ A make_A();
bool operator==(A&, Z&); // expected-note 3{{candidate function}}
void h(A a, const A ac, Z z) {
- make_A() == z;
+ make_A() == z; // expected-warning{{equality comparison result unused}}
a == z; // expected-error{{use of overloaded operator '==' is ambiguous}}
ac == z; // expected-error{{invalid operands to binary expression ('const A' and 'Z')}}
}
@@ -45,7 +45,7 @@ struct B {
bool operator==(const B&) const;
void test(Z z) {
- make_A() == z;
+ make_A() == z; // expected-warning{{equality comparison result unused}}
}
};
@@ -396,7 +396,7 @@ namespace rdar9136502 {
};
void f(X x, Y y) {
- y << x.i; // expected-error{{a bound member function may only be called}}
+ y << x.i; // expected-error{{reference to non-static member function must be called}}
}
}
diff --git a/test/SemaCXX/ptrtomember-overload-resolution.cpp b/test/SemaCXX/ptrtomember-overload-resolution.cpp
index 4c7908e1137e..787e33022aa3 100644
--- a/test/SemaCXX/ptrtomember-overload-resolution.cpp
+++ b/test/SemaCXX/ptrtomember-overload-resolution.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
// 13.3.3.2 Ranking implicit conversion sequences
// conversion of A::* to B::* is better than conversion of A::* to C::*,
diff --git a/test/SemaCXX/ptrtomember.cpp b/test/SemaCXX/ptrtomember.cpp
index c3917333a540..aee535e5593b 100644
--- a/test/SemaCXX/ptrtomember.cpp
+++ b/test/SemaCXX/ptrtomember.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
struct S {
int i;
@@ -22,12 +22,12 @@ struct S3 {
};
void f3(S3* p, void (S3::*m)()) {
- p->*m; // expected-error {{a bound member function may only be called}}
- (void)(p->*m); // expected-error {{a bound member function may only be called}}
- (void)(void*)(p->*m); // expected-error {{a bound member function may only be called}}
- (void)reinterpret_cast<void*>(p->*m); // expected-error {{a bound member function may only be called}}
- if (p->*m) {} // expected-error {{a bound member function may only be called}}
- if (!(p->*m)) {} // expected-error {{a bound member function may only be called}}
- if (p->m) {}; // expected-error {{a bound member function may only be called}}
- if (!p->m) {}; // expected-error {{a bound member function may only be called}}
+ p->*m; // expected-error {{reference to non-static member function must be called}}
+ (void)(p->*m); // expected-error {{reference to non-static member function must be called}}
+ (void)(void*)(p->*m); // expected-error {{reference to non-static member function must be called}} expected-error {{cannot cast from type 'void' to pointer type 'void *'}}
+ (void)reinterpret_cast<void*>(p->*m); // expected-error {{reference to non-static member function must be called}} expected-error {{reinterpret_cast from 'void' to 'void *' is not allowed}}
+ if (p->*m) {} // expected-error {{reference to non-static member function must be called}} expected-error {{value of type 'void' is not contextually convertible to 'bool'}}
+ if (!(p->*m)) {} // expected-error {{reference to non-static member function must be called}} expected-error {{invalid argument type 'void' to unary expression}}
+ if (p->m) {}; // expected-error {{reference to non-static member function must be called}} expected-error {{value of type 'void' is not contextually convertible to 'bool'}}
+ if (!p->m) {}; // expected-error {{reference to non-static member function must be called}} expected-error {{invalid argument type 'void' to unary expression}}
}
diff --git a/test/SemaCXX/redeclared-alias-template.cpp b/test/SemaCXX/redeclared-alias-template.cpp
index b368fcfe5508..09e9d0d83bf5 100644
--- a/test/SemaCXX/redeclared-alias-template.cpp
+++ b/test/SemaCXX/redeclared-alias-template.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
template<typename T> using A = int; // expected-note 2{{previous}}
template<typename T> using A = char; // expected-error {{type alias template redefinition with different types ('char' vs 'int')}}
diff --git a/test/SemaCXX/redeclared-auto.cpp b/test/SemaCXX/redeclared-auto.cpp
index 34de54c0f01d..87ad6bd7e5d8 100644
--- a/test/SemaCXX/redeclared-auto.cpp
+++ b/test/SemaCXX/redeclared-auto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
extern int a;
auto a = 0; // expected-note 2{{here}}
diff --git a/test/SemaCXX/ref-init-ambiguous.cpp b/test/SemaCXX/ref-init-ambiguous.cpp
index 752a3484d025..ce47e10c9ae3 100644
--- a/test/SemaCXX/ref-init-ambiguous.cpp
+++ b/test/SemaCXX/ref-init-ambiguous.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
enum E2 { };
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index ab44e78453b2..70d3799a0ea5 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -134,3 +134,6 @@ namespace PR7149 {
namespace PR8608 {
bool& f(unsigned char& c) { return (bool&)c; }
}
+
+// The following crashed trying to recursively evaluate the LValue.
+const int &do_not_crash = do_not_crash;
diff --git a/test/SemaCXX/return-noreturn.cpp b/test/SemaCXX/return-noreturn.cpp
index 53ed0d724527..e06ba403efec 100644
--- a/test/SemaCXX/return-noreturn.cpp
+++ b/test/SemaCXX/return-noreturn.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code
+// RUN: %clang_cc1 %s -fsyntax-only -std=c++11 -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code
// A destructor may be marked noreturn and should still influence the CFG.
void pr6884_abort() __attribute__((noreturn));
@@ -8,23 +9,93 @@ struct pr6884_abort_struct {
~pr6884_abort_struct() __attribute__((noreturn)) { pr6884_abort(); }
};
-int pr6884_f(int x) {
- switch (x) { default: pr6884_abort(); }
-}
+struct other { ~other() {} };
-int pr6884_g(int x) {
- switch (x) { default: pr6884_abort_struct(); }
-}
+// Ensure that destructors from objects are properly modeled in the CFG despite
+// the presence of switches, case statements, labels, and blocks. These tests
+// try to cover bugs reported in both PR6884 and PR10063.
+namespace abort_struct_complex_cfgs {
+ int basic(int x) {
+ switch (x) { default: pr6884_abort(); }
+ }
+ int f1(int x) {
+ switch (x) default: pr6884_abort_struct();
+ }
+ int f2(int x) {
+ switch (x) { default: pr6884_abort_struct(); }
+ }
+ int f2_positive(int x) {
+ switch (x) { default: ; }
+ } // expected-warning {{control reaches end of non-void function}}
+ int f3(int x) {
+ switch (x) { default: { pr6884_abort_struct(); } }
+ }
+ int f4(int x) {
+ switch (x) default: L1: L2: case 4: pr6884_abort_struct();
+ }
+ int f5(int x) {
+ switch (x) default: L1: { L2: case 4: pr6884_abort_struct(); }
+ }
+ int f6(int x) {
+ switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); }
+ }
-int pr6884_g_positive(int x) {
- switch (x) { default: ; }
-} // expected-warning {{control reaches end of non-void function}}
+ // Test that these constructs work even when extraneous blocks are created
+ // before and after the switch due to implicit destructors.
+ int g1(int x) {
+ other o;
+ switch (x) default: pr6884_abort_struct();
+ }
+ int g2(int x) {
+ other o;
+ switch (x) { default: pr6884_abort_struct(); }
+ }
+ int g2_positive(int x) {
+ other o;
+ switch (x) { default: ; }
+ } // expected-warning {{control reaches end of non-void function}}
+ int g3(int x) {
+ other o;
+ switch (x) { default: { pr6884_abort_struct(); } }
+ }
+ int g4(int x) {
+ other o;
+ switch (x) default: L1: L2: case 4: pr6884_abort_struct();
+ }
+ int g5(int x) {
+ other o;
+ switch (x) default: L1: { L2: case 4: pr6884_abort_struct(); }
+ }
+ int g6(int x) {
+ other o;
+ switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); }
+ }
-int pr6884_h(int x) {
- switch (x) {
- default: {
- pr6884_abort_struct a;
- }
+ // Test that these constructs work even with variables carrying the no-return
+ // destructor instead of temporaries.
+ int h1(int x) {
+ other o;
+ switch (x) default: pr6884_abort_struct a;
+ }
+ int h2(int x) {
+ other o;
+ switch (x) { default: pr6884_abort_struct a; }
+ }
+ int h3(int x) {
+ other o;
+ switch (x) { default: { pr6884_abort_struct a; } }
+ }
+ int h4(int x) {
+ other o;
+ switch (x) default: L1: L2: case 4: pr6884_abort_struct a;
+ }
+ int h5(int x) {
+ other o;
+ switch (x) default: L1: { L2: case 4: pr6884_abort_struct a; }
+ }
+ int h6(int x) {
+ other o;
+ switch (x) default: L1: L2: case 4: { pr6884_abort_struct a; }
}
}
diff --git a/test/SemaCXX/rval-references-examples.cpp b/test/SemaCXX/rval-references-examples.cpp
index f4921a9b5168..110ae26fb5d2 100644
--- a/test/SemaCXX/rval-references-examples.cpp
+++ b/test/SemaCXX/rval-references-examples.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
template<typename T>
class unique_ptr {
diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp
index 74afdbe41043..fc341e87f4a4 100644
--- a/test/SemaCXX/rval-references.cpp
+++ b/test/SemaCXX/rval-references.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s
typedef int&& irr;
typedef irr& ilr_c1; // Collapses to int&
diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp
index 3a90cc08f6a2..ad109f4d4e03 100644
--- a/test/SemaCXX/scope-check.cpp
+++ b/test/SemaCXX/scope-check.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-unreachable-code
-// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++0x %s -Wno-unreachable-code
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++11 %s -Wno-unreachable-code
namespace test0 {
struct D { ~D(); };
@@ -171,3 +171,39 @@ namespace test9 {
}
}
}
+
+// http://llvm.org/PR10462
+namespace PR10462 {
+enum MyEnum {
+ something_valid,
+ something_invalid
+};
+
+bool recurse() {
+ MyEnum K;
+ switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}}
+ case something_valid:
+ case what_am_i_thinking: // expected-error {{use of undeclared identifier}}
+ int *X = 0;
+ if (recurse()) {
+ }
+
+ break;
+ }
+}
+
+
+namespace test10 {
+
+int test() {
+ static void *ps[] = { &&a0 };
+ goto *&&a0; // expected-error {{goto into protected scope}}
+ int a = 3; // expected-note {{jump bypasses variable initialization}}
+ a0:
+ return 0;
+}
+
+}
+
+}
+
diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp
index 516243ec70e1..0991a5f89cc8 100644
--- a/test/SemaCXX/static-assert.cpp
+++ b/test/SemaCXX/static-assert.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
int f();
diff --git a/test/SemaCXX/switch-0x.cpp b/test/SemaCXX/switch-0x.cpp
index adaeb85bce17..2e74da0a4634 100644
--- a/test/SemaCXX/switch-0x.cpp
+++ b/test/SemaCXX/switch-0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// PR5518
struct A {
diff --git a/test/SemaCXX/trailing-return-0x.cpp b/test/SemaCXX/trailing-return-0x.cpp
index b52b240da35d..e25939fa3ebf 100644
--- a/test/SemaCXX/trailing-return-0x.cpp
+++ b/test/SemaCXX/trailing-return-0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
template <class T>
struct only
diff --git a/test/SemaCXX/trivial-constructor.cpp b/test/SemaCXX/trivial-constructor.cpp
index 494d1ec0843f..bda206b61f9a 100644
--- a/test/SemaCXX/trivial-constructor.cpp
+++ b/test/SemaCXX/trivial-constructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
struct T1 {
};
static_assert(__has_trivial_constructor(T1), "T1 has trivial constructor!");
diff --git a/test/SemaCXX/trivial-destructor.cpp b/test/SemaCXX/trivial-destructor.cpp
index 29358d8bd228..db415cf9050a 100644
--- a/test/SemaCXX/trivial-destructor.cpp
+++ b/test/SemaCXX/trivial-destructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
struct T1 {
};
static_assert(__has_trivial_destructor(T1), "T1 has trivial destructor!");
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index 30cc6a3f1ce2..0914c7cf94e3 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++0x %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 %s
#define T(b) (b) ? 1 : -1
#define F(b) (b) ? -1 : 1
@@ -89,6 +89,13 @@ struct HasVirtDest { virtual ~HasVirtDest(); };
struct DerivedVirtDest : HasVirtDest {};
typedef HasVirtDest VirtDestAr[1];
+class AllPrivate {
+ AllPrivate() throw();
+ AllPrivate(const AllPrivate&) throw();
+ AllPrivate &operator=(const AllPrivate &) throw();
+ ~AllPrivate() throw();
+};
+
void is_pod()
{
{ int arr[T(__is_pod(int))]; }
@@ -1102,6 +1109,7 @@ void has_trivial_default_constructor() {
{ int arr[F(__has_trivial_constructor(void))]; }
{ int arr[F(__has_trivial_constructor(cvoid))]; }
{ int arr[F(__has_trivial_constructor(HasTemplateCons))]; }
+ { int arr[F(__has_trivial_constructor(AllPrivate))]; }
}
void has_trivial_copy_constructor() {
@@ -1129,6 +1137,7 @@ void has_trivial_copy_constructor() {
{ int arr[F(__has_trivial_copy(VirtAr))]; }
{ int arr[F(__has_trivial_copy(void))]; }
{ int arr[F(__has_trivial_copy(cvoid))]; }
+ { int arr[F(__has_trivial_copy(AllPrivate))]; }
}
void has_trivial_copy_assignment() {
@@ -1155,6 +1164,7 @@ void has_trivial_copy_assignment() {
{ int arr[F(__has_trivial_assign(VirtAr))]; }
{ int arr[F(__has_trivial_assign(void))]; }
{ int arr[F(__has_trivial_assign(cvoid))]; }
+ { int arr[F(__has_trivial_assign(AllPrivate))]; }
}
void has_trivial_destructor() {
@@ -1181,6 +1191,7 @@ void has_trivial_destructor() {
{ int arr[F(__has_trivial_destructor(HasDest))]; }
{ int arr[F(__has_trivial_destructor(void))]; }
{ int arr[F(__has_trivial_destructor(cvoid))]; }
+ { int arr[F(__has_trivial_destructor(AllPrivate))]; }
}
struct A { ~A() {} };
@@ -1191,6 +1202,23 @@ void f() {
{ int arr[F(__has_trivial_destructor(B<int>))]; }
}
+class PR11110 {
+ template <int> int operator=( int );
+ int operator=(PR11110);
+};
+
+class UsingAssign;
+
+class UsingAssignBase {
+protected:
+ UsingAssign &operator=(const UsingAssign&) throw();
+};
+
+class UsingAssign : public UsingAssignBase {
+public:
+ using UsingAssignBase::operator=;
+};
+
void has_nothrow_assign() {
{ int arr[T(__has_nothrow_assign(Int))]; }
{ int arr[T(__has_nothrow_assign(IntAr))]; }
@@ -1208,6 +1236,8 @@ void has_nothrow_assign() {
{ int arr[T(__has_nothrow_assign(HasNoThrowCopyAssign))]; }
{ int arr[T(__has_nothrow_assign(HasMultipleNoThrowCopyAssign))]; }
{ int arr[T(__has_nothrow_assign(HasVirtDest))]; }
+ { int arr[T(__has_nothrow_assign(AllPrivate))]; }
+ { int arr[T(__has_nothrow_assign(UsingAssign))]; }
{ int arr[F(__has_nothrow_assign(IntRef))]; }
{ int arr[F(__has_nothrow_assign(HasCopyAssign))]; }
@@ -1219,6 +1249,7 @@ void has_nothrow_assign() {
{ int arr[F(__has_nothrow_assign(VirtAr))]; }
{ int arr[F(__has_nothrow_assign(void))]; }
{ int arr[F(__has_nothrow_assign(cvoid))]; }
+ { int arr[F(__has_nothrow_assign(PR11110))]; }
}
void has_nothrow_copy() {
@@ -1243,6 +1274,7 @@ void has_nothrow_copy() {
{ int arr[T(__has_nothrow_copy(HasMultipleNoThrowCopy))]; }
{ int arr[T(__has_nothrow_copy(HasVirtDest))]; }
{ int arr[T(__has_nothrow_copy(HasTemplateCons))]; }
+ { int arr[T(__has_nothrow_copy(AllPrivate))]; }
{ int arr[F(__has_nothrow_copy(HasCopy))]; }
{ int arr[F(__has_nothrow_copy(HasMultipleCopy))]; }
@@ -1272,6 +1304,7 @@ void has_nothrow_constructor() {
{ int arr[T(__has_nothrow_constructor(HasNoThrowConstructor))]; }
{ int arr[T(__has_nothrow_constructor(HasVirtDest))]; }
// { int arr[T(__has_nothrow_constructor(VirtAr))]; } // not implemented
+ { int arr[T(__has_nothrow_constructor(AllPrivate))]; }
{ int arr[F(__has_nothrow_constructor(HasCons))]; }
{ int arr[F(__has_nothrow_constructor(HasRef))]; }
@@ -1316,6 +1349,7 @@ void has_virtual_destructor() {
{ int arr[F(__has_virtual_destructor(VirtDestAr))]; }
{ int arr[F(__has_virtual_destructor(void))]; }
{ int arr[F(__has_virtual_destructor(cvoid))]; }
+ { int arr[F(__has_virtual_destructor(AllPrivate))]; }
}
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
new file mode 100644
index 000000000000..fa32c57fc7ed
--- /dev/null
+++ b/test/SemaCXX/typo-correction.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-c++0x-extensions %s
+
+struct errc {
+ int v_;
+ operator int() const {return v_;}
+};
+
+class error_condition
+{
+ int _val_;
+public:
+ error_condition() : _val_(0) {}
+
+ error_condition(int _val)
+ : _val_(_val) {}
+
+ template <class E>
+ error_condition(E _e) {
+ // make_error_condition must not be typo corrected to error_condition
+ // even though the first declaration of make_error_condition has not
+ // yet been encountered. This was a bug in the first version of the type
+ // name typo correction patch that wasn't noticed until building LLVM with
+ // Clang failed.
+ *this = make_error_condition(_e);
+ }
+
+};
+
+inline error_condition make_error_condition(errc _e) {
+ return error_condition(static_cast<int>(_e));
+}
diff --git a/test/SemaCXX/underlying_type.cpp b/test/SemaCXX/underlying_type.cpp
index 607d9ad843a4..dcfaab3c8b4d 100644
--- a/test/SemaCXX/underlying_type.cpp
+++ b/test/SemaCXX/underlying_type.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -ffreestanding -fsyntax-only -verify -std=c++0x %s
+// RUN: %clang_cc1 -ffreestanding -fsyntax-only -verify -std=c++11 %s
#include "limits.h"
diff --git a/test/SemaCXX/uninit-variables-conditional.cpp b/test/SemaCXX/uninit-variables-conditional.cpp
index 3324215621bf..3c44c7249d51 100644
--- a/test/SemaCXX/uninit-variables-conditional.cpp
+++ b/test/SemaCXX/uninit-variables-conditional.cpp
@@ -15,7 +15,7 @@ int init(double *);
// the destructor in Foo fouls about the minor bit of path-sensitivity in
// -Wuninitialized.
double test() {
- double x; // expected-note {{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
+ double x; // expected-note{{initialize the variable 'x' to silence this warning}}
if (bar() || baz() || Foo() || init(&x))
return 1.0;
diff --git a/test/SemaCXX/uninit-variables.cpp b/test/SemaCXX/uninit-variables.cpp
index a0180e3d3a15..358a5723563f 100644
--- a/test/SemaCXX/uninit-variables.cpp
+++ b/test/SemaCXX/uninit-variables.cpp
@@ -26,7 +26,7 @@ void unevaluated_tests() {
// Warn for glvalue arguments to typeid whose type is polymorphic.
struct A { virtual ~A() {} };
void polymorphic_test() {
- A *a; // expected-note{{declared here}} expected-note{{add initialization}}
+ A *a; // expected-note{{initialize the variable 'a' to silence this warning}}
(void)typeid(*a); // expected-warning{{variable 'a' is uninitialized when used here }}
}
@@ -50,7 +50,7 @@ unsigned test3_b() {
return x; // no-warning
}
unsigned test3_c() {
- unsigned x; // expected-note{{declared here}} expected-note{{add initialization}}
+ unsigned x; // expected-note{{initialize the variable 'x' to silence this warning}}
const bool flag = false;
if (flag && (x = test3_aux()) == 0) {
x = 1;
@@ -66,6 +66,16 @@ test4_A test4() {
return a; // expected-warning{{variable 'a' is uninitialized when used here}}
}
+// Test variables getting invalidated by function calls with reference arguments
+// *AND* there are multiple invalidated arguments.
+void test5_aux(int &, int &);
+
+int test5() {
+ int x, y;
+ test5_aux(x, y);
+ return x + y; // no-warning
+}
+
// This test previously crashed Sema.
class Rdar9188004A {
public:
@@ -108,4 +118,26 @@ void RDar9251392() {
}
}
+// Test handling of "no-op" casts.
+void test_noop_cast()
+{
+ int x = 1;
+ int y = (int&)x; // no-warning
+}
+
+void test_noop_cast2() {
+ int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+ int y = (int&)x; // expected-warning {{uninitialized when used here}}
+}
+
+// Test handling of bit casts.
+void test_bitcasts() {
+ int x = 1;
+ int y = (float &)x; // no-warning
+}
+
+void test_bitcasts_2() {
+ int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+ int y = (float &)x; // expected-warning {{uninitialized when used here}}
+}
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index 0a3b5d938dd3..c25bd201d626 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -24,6 +24,78 @@ int i = boo(i);
int j = far(j);
int k = __alignof__(k);
+
+// Test self-references with record types.
+class A {
+ // Non-POD class.
+ public:
+ enum count { ONE, TWO, THREE };
+ int num;
+ static int count;
+ int get() const { return num; }
+ void set(int x) { num = x; }
+ static int zero() { return 0; }
+
+ A() {}
+ A(A const &a) {}
+ A(int x) {}
+ A(int *x) {}
+ A(A *a) {}
+};
+
+A getA() { return A(); }
+A getA(int x) { return A(); }
+A getA(A* a) { return A(); }
+
+void setupA() {
+ A a1;
+ a1.set(a1.get());
+ 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}}
+}
+
+struct B {
+ // POD struct.
+ int x;
+ int *y;
+};
+
+B getB() { return B(); };
+B getB(int x) { return B(); };
+B getB(int *x) { return B(); };
+B getB(B *b) { return B(); };
+
+void setupB() {
+ B b1;
+ B b2(b1);
+ B b3 = { 5, &b3.x };
+ B b4 = getB();
+ B b5 = getB(&b5);
+ B b6 = getB(&b6.x);
+
+ // Silence unused warning
+ (void) b2;
+ (void) b4;
+
+ 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}}
+}
+
// Also test similar constructs in a field's initializer.
struct S {
int x;
@@ -43,3 +115,5 @@ struct S {
S(char (*)[5]) : x(boo(x)) {}
S(char (*)[6]) : x(far(x)) {}
};
+
+struct C { char a[100], *e; } car = { .e = car.a };
diff --git a/test/SemaCXX/unknown-anytype.cpp b/test/SemaCXX/unknown-anytype.cpp
index b0a2981f470d..ba52122bc490 100644
--- a/test/SemaCXX/unknown-anytype.cpp
+++ b/test/SemaCXX/unknown-anytype.cpp
@@ -34,3 +34,14 @@ namespace test3 {
((void(void)) foo)(); // expected-error {{variable 'foo' with unknown type cannot be given a function type}}
}
}
+
+// rdar://problem/9899447
+namespace test4 {
+ extern __unknown_anytype test0(...);
+ extern __unknown_anytype test1(...);
+
+ void test() {
+ void (*fn)(int) = (void(*)(int)) test0;
+ int x = (int) test1; // expected-error {{function 'test1' with unknown type must be given a function type}}
+ }
+}
diff --git a/test/SemaCXX/unused-functions.cpp b/test/SemaCXX/unused-functions.cpp
index f164bf276846..359808203892 100644
--- a/test/SemaCXX/unused-functions.cpp
+++ b/test/SemaCXX/unused-functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -Wunused -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wunused -verify %s
static int foo(int x) { return x; }
diff --git a/test/SemaCXX/user-defined-conversions.cpp b/test/SemaCXX/user-defined-conversions.cpp
index 5de7f44be92c..43ec5a3d4ab9 100644
--- a/test/SemaCXX/user-defined-conversions.cpp
+++ b/test/SemaCXX/user-defined-conversions.cpp
@@ -82,3 +82,18 @@ float &f(...);
void g(X2 b) {
int &ir = f(b); // expected-error{{no viable constructor copying parameter of type 'X1'}}
}
+
+namespace rdar10202900 {
+ class A {
+ public:
+ A();
+
+ private:
+ A(int i); // expected-note{{declared private here}}
+ };
+
+ void testA(A a) {
+ int b = 10;
+ a = b; // expected-error{{calling a private constructor of class 'rdar10202900::A'}}
+ }
+}
diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp
index 7b4da9d50d03..2f8abca02d6e 100644
--- a/test/SemaCXX/using-decl-templates.cpp
+++ b/test/SemaCXX/using-decl-templates.cpp
@@ -63,3 +63,20 @@ template <class T> struct Bar : public Foo<T>, Baz {
};
template int Bar<int>::foo();
}
+
+// PR10883
+namespace PR10883 {
+ template <typename T>
+ class Base {
+ public:
+ typedef long Container;
+ };
+
+ template <typename T>
+ class Derived : public Base<T> {
+ public:
+ using Base<T>::Container;
+
+ void foo(const Container& current); // expected-error {{unknown type name 'Container'}}
+ };
+}
diff --git a/test/SemaCXX/value-initialization.cpp b/test/SemaCXX/value-initialization.cpp
index dfe0f46ea255..19be03af8f46 100644
--- a/test/SemaCXX/value-initialization.cpp
+++ b/test/SemaCXX/value-initialization.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
struct A { //expected-note {{marked deleted here}} \
// expected-warning {{does not declare any constructor to initialize}}
diff --git a/test/SemaCXX/vararg-non-pod.cpp b/test/SemaCXX/vararg-non-pod.cpp
index 3ca07b0215c3..42c27fb30e1b 100644
--- a/test/SemaCXX/vararg-non-pod.cpp
+++ b/test/SemaCXX/vararg-non-pod.cpp
@@ -118,4 +118,3 @@ void t8(int n, ...) {
(void)__builtin_va_arg(list, Abstract); // expected-error{{second argument to 'va_arg' is of abstract type 'Abstract'}}
__builtin_va_end(list);
}
-
diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp
index 23d86d37426e..b477438ee988 100644
--- a/test/SemaCXX/virtual-override.cpp
+++ b/test/SemaCXX/virtual-override.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
namespace T1 {
class A {
diff --git a/test/SemaCXX/virtuals.cpp b/test/SemaCXX/virtuals.cpp
index d8c26efcfb42..ea7d203ca70f 100644
--- a/test/SemaCXX/virtuals.cpp
+++ b/test/SemaCXX/virtuals.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++0x %s
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 %s
class A {
virtual void f();
diff --git a/test/SemaCXX/warn-assignment-condition.cpp b/test/SemaCXX/warn-assignment-condition.cpp
index c0ef35b252d8..04f2e7952547 100644
--- a/test/SemaCXX/warn-assignment-condition.cpp
+++ b/test/SemaCXX/warn-assignment-condition.cpp
@@ -109,6 +109,12 @@ void test() {
if ((x == 5)) {} // expected-warning {{equality comparison with extraneous parentheses}} \
// expected-note {{use '=' to turn this equality comparison into an assignment}} \
// expected-note {{remove extraneous parentheses around the comparison to silence this warning}}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wparentheses-equality"
+ if ((x == 5)) {} // no-warning
+#pragma clang diagnostic pop
+
if ((5 == x)) {}
#define EQ(x,y) ((x) == (y))
diff --git a/test/SemaCXX/warn-bad-memaccess.cpp b/test/SemaCXX/warn-bad-memaccess.cpp
index 9a998f020cb4..3a02c84e9fc4 100644
--- a/test/SemaCXX/warn-bad-memaccess.cpp
+++ b/test/SemaCXX/warn-bad-memaccess.cpp
@@ -3,6 +3,7 @@
extern "C" void *memset(void *, int, unsigned);
extern "C" void *memmove(void *s1, const void *s2, unsigned n);
extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
+extern "C" void *memcmp(void *s1, const void *s2, unsigned n);
// Several types that should not warn.
struct S1 {} s1;
@@ -27,16 +28,22 @@ void test_warn() {
// expected-note {{explicitly cast the pointer to silence this warning}}
memmove(&x1, 0, sizeof x1); // \
- // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class}} \
+ // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
memmove(0, &x1, sizeof x1); // \
- // expected-warning{{source of this 'memmove' call is a pointer to dynamic class}} \
+ // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be moved}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
memcpy(&x1, 0, sizeof x1); // \
- // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class}} \
+ // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
memcpy(0, &x1, sizeof x1); // \
- // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class}} \
+ // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be copied}} \
+ // expected-note {{explicitly cast the pointer to silence this warning}}
+ memcmp(&x1, 0, sizeof x1); // \
+ // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
+ // expected-note {{explicitly cast the pointer to silence this warning}}
+ memcmp(0, &x1, sizeof x1); // \
+ // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
// expected-note {{explicitly cast the pointer to silence this warning}}
__builtin_memset(&x1, 0, sizeof x1); // \
@@ -108,5 +115,3 @@ namespace N {
N::memset(&x1, 0, sizeof x1);
}
}
-
-
diff --git a/test/SemaCXX/warn-bool-conversion.cpp b/test/SemaCXX/warn-bool-conversion.cpp
index f6fa9f28369d..595c749bcecd 100644
--- a/test/SemaCXX/warn-bool-conversion.cpp
+++ b/test/SemaCXX/warn-bool-conversion.cpp
@@ -1,18 +1,18 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-int* j = false; // expected-warning{{ initialization of pointer of type 'int *' to NULL from a constant boolean expression}}
+int* j = false; // expected-warning{{ initialization of pointer of type 'int *' to null from a constant boolean expression}}
-void foo(int* i, int *j=(false)) // expected-warning{{ initialization of pointer of type 'int *' to NULL from a constant boolean expression}}
+void foo(int* i, int *j=(false)) // expected-warning{{ initialization of pointer of type 'int *' to null from a constant boolean expression}}
{
- foo(false); // expected-warning{{ initialization of pointer of type 'int *' to NULL from a constant boolean expression}}
+ foo(false); // expected-warning{{ initialization of pointer of type 'int *' to null from a constant boolean expression}}
foo((int*)false); // no-warning: explicit cast
foo(0); // no-warning: not a bool, even though its convertible to bool
- foo(false == true); // expected-warning{{ initialization of pointer of type 'int *' to NULL from a constant boolean expression}}
- foo((42 + 24) < 32); // expected-warning{{ initialization of pointer of type 'int *' to NULL from a constant boolean expression}}
+ foo(false == true); // expected-warning{{ initialization of pointer of type 'int *' to null from a constant boolean expression}}
+ foo((42 + 24) < 32); // expected-warning{{ initialization of pointer of type 'int *' to null from a constant boolean expression}}
const bool kFlag = false;
- foo(kFlag); // expected-warning{{ initialization of pointer of type 'int *' to NULL from a constant boolean expression}}
+ foo(kFlag); // expected-warning{{ initialization of pointer of type 'int *' to null from a constant boolean expression}}
}
char f(struct Undefined*);
diff --git a/test/SemaCXX/warn-dangling-field.cpp b/test/SemaCXX/warn-dangling-field.cpp
new file mode 100644
index 000000000000..95f8c61ebb77
--- /dev/null
+++ b/test/SemaCXX/warn-dangling-field.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -fsyntax-only -Wdangling-field -verify %s
+
+struct X {
+ X(int);
+};
+struct Y {
+ operator X*();
+ operator X&();
+};
+
+struct S {
+ int &x, *y; // expected-note {{reference member declared here}} \
+ // expected-note {{pointer member declared here}}
+ S(int i)
+ : x(i), // expected-warning {{binding reference member 'x' to stack allocated parameter 'i'}}
+ y(&i) {} // expected-warning {{initializing pointer member 'y' with the stack address of parameter 'i'}}
+ S(int &i) : x(i), y(&i) {} // no-warning: reference parameter
+ S(int *i) : x(*i), y(i) {} // no-warning: pointer parameter
+};
+
+struct S2 {
+ const X &x; // expected-note {{reference member declared here}}
+ S2(int i) : x(i) {} // expected-warning {{binding reference member 'x' to a temporary}}
+};
+
+struct S3 {
+ X &x1, *x2;
+ S3(Y y) : x1(y), x2(y) {} // no-warning: conversion operator
+};
+
+template <typename T> struct S4 {
+ T x; // expected-note {{reference member declared here}}
+ S4(int i) : x(i) {} // expected-warning {{binding reference member 'x' to stack allocated parameter 'i'}}
+};
+
+template struct S4<int>; // no warning from this instantiation
+template struct S4<int&>; // expected-note {{in instantiation}}
diff --git a/test/SemaCXX/warn-literal-conversion.cpp b/test/SemaCXX/warn-literal-conversion.cpp
index b9c952873b9f..5fcae5dc80e6 100644
--- a/test/SemaCXX/warn-literal-conversion.cpp
+++ b/test/SemaCXX/warn-literal-conversion.cpp
@@ -8,18 +8,13 @@ void test0() {
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 = 12E1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}} \
- // expected-note {{this can be rewritten as an integer literal with the exact same value}}
- int y4 = 1.2E1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}} \
- // expected-note {{this can be rewritten as an integer literal with the exact same value}}
+ 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}}
// Double
int y5 = 1.2222; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
- int y6 = 12E1; // expected-warning {{implicit conversion turns literal floating-point number into integer}} \
- // expected-note {{this can be rewritten as an integer literal with the exact same value}}
- int y7 = 1.2E1; // expected-warning {{implicit conversion turns literal floating-point number into integer}} \
- // expected-note {{this can be rewritten as an integer literal with the exact same value}}
- int y8 = (1.2E1); // expected-warning {{implicit conversion turns literal floating-point number into integer}} \
- // expected-note {{this can be rewritten as an integer literal with the exact same value}}
+ 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}}
// Test assignment to an existing variable.
y8 = 2.22F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
@@ -30,8 +25,7 @@ void test0() {
// 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}}
- // FIXME: -Wconversion-literal doesn't catch "-1.2F".
- int y10 = -1.2F;
+ int y10 = -1.2F; // expected-warning {{implicit conversion turns literal floating-point number into integer}}
// -Wconversion-literal does NOT catch const values.
// (-Wconversion DOES catch them.)
diff --git a/test/SemaCXX/warn-memset-bad-sizeof.cpp b/test/SemaCXX/warn-memset-bad-sizeof.cpp
index 90ac50472e98..a018223cbdae 100644
--- a/test/SemaCXX/warn-memset-bad-sizeof.cpp
+++ b/test/SemaCXX/warn-memset-bad-sizeof.cpp
@@ -3,6 +3,7 @@
extern "C" void *memset(void *, int, unsigned);
extern "C" void *memmove(void *s1, const void *s2, unsigned n);
extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
+extern "C" void *memcmp(void *s1, const void *s2, unsigned n);
struct S {int a, b, c, d;};
typedef S* PS;
@@ -51,6 +52,11 @@ void f(Mat m, const Foo& const_foo, char *buffer) {
memcpy(0, &s, sizeof(&s)); // \
// expected-warning {{argument to 'sizeof' in 'memcpy' call is the same expression as the source}}
+ memmove(ps, 0, sizeof(ps)); // \
+ // expected-warning {{argument to 'sizeof' in 'memmove' call is the same expression as the destination}}
+ memcmp(ps, 0, sizeof(ps)); // \
+ // expected-warning {{argument to 'sizeof' in 'memcmp' call is the same expression as the destination}}
+
/* Shouldn't warn */
memset((void*)&s, 0, sizeof(&s));
memset(&s, 0, sizeof(s));
@@ -99,3 +105,35 @@ void f(Mat m, const Foo& const_foo, char *buffer) {
memcpy(&foo, &arr, sizeof(Foo));
memcpy(&arr, &foo, sizeof(Foo));
}
+
+namespace ns {
+void memset(void* s, char c, int n);
+void f(int* i) {
+ memset(i, 0, sizeof(i));
+}
+}
+
+extern "C" int strncmp(const char *s1, const char *s2, unsigned n);
+extern "C" int strncasecmp(const char *s1, const char *s2, unsigned n);
+extern "C" char *strncpy(char *det, const char *src, unsigned n);
+extern "C" char *strncat(char *dst, const char *src, unsigned n);
+extern "C" char *strndup(const char *src, unsigned n);
+
+void strcpy_and_friends() {
+ const char* FOO = "<- should be an array instead";
+ 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}}
+ strncasecmp(FOO, BAR, sizeof(FOO)); // \
+ // expected-warning {{argument to 'sizeof' in 'strncasecmp' call is the same expression as the destination}}
+
+ char buff[80];
+
+ strncpy(buff, BAR, sizeof(BAR)); // \
+ // expected-warning {{argument to 'sizeof' in 'strncpy' call is the same expression as the source}}
+ strncat(buff, BAR, sizeof(BAR)); // \
+ // expected-warning {{argument to 'sizeof' in 'strncat' call is the same expression as the source}}
+ strndup(FOO, sizeof(FOO)); // \
+ // expected-warning {{argument to 'sizeof' in 'strndup' call is the same expression as the source}}
+}
diff --git a/test/SemaCXX/warn-missing-noreturn.cpp b/test/SemaCXX/warn-missing-noreturn.cpp
index 4caff66af703..8072ac6b8249 100644
--- a/test/SemaCXX/warn-missing-noreturn.cpp
+++ b/test/SemaCXX/warn-missing-noreturn.cpp
@@ -1,27 +1,27 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -Wmissing-noreturn -Wreturn-type
void f() __attribute__((noreturn));
-template<typename T> void g(T) { // expected-warning {{function could be attribute 'noreturn'}}
+template<typename T> void g(T) {
f();
}
-template void g<int>(int); // expected-note {{in instantiation of function template specialization 'g<int>' requested here}}
+template void g<int>(int);
template<typename T> struct A {
- void g() { // expected-warning {{function could be attribute 'noreturn'}}
+ void g() {
f();
}
};
-template struct A<int>; // expected-note {{in instantiation of member function 'A<int>::g' requested here}}
+template struct A<int>;
struct B {
- template<typename T> void g(T) { // expected-warning {{function could be attribute 'noreturn'}}
+ template<typename T> void g(T) {
f();
}
};
-template void B::g<int>(int); // expected-note {{in instantiation of function template specialization 'B::g<int>' requested here}}
+template void B::g<int>(int);
// We don't want a warning here.
struct X {
@@ -61,7 +61,7 @@ namespace test2 {
void *f;
A() : f(0) { }
- A(int) : f(h()) { } // expected-warning {{function could be attribute 'noreturn'}}
+ A(int) : f(h()) { } // expected-warning {{function 'A' could be declared with attribute 'noreturn'}}
A(char) : f(j()) { }
A(bool b) : f(b ? h() : j()) { }
};
@@ -103,3 +103,23 @@ rdar8875247_B test_rdar8875247_B() {
return f;
} // no-warning
+namespace PR10801 {
+ struct Foo {
+ void wibble() __attribute((__noreturn__));
+ };
+
+ struct Bar {
+ void wibble();
+ };
+
+ template <typename T> void thingy(T thing) {
+ thing.wibble();
+ }
+
+ void test() {
+ Foo f;
+ Bar b;
+ thingy(f);
+ thingy(b);
+ }
+}
diff --git a/test/SemaCXX/warn-sign-compare.cpp b/test/SemaCXX/warn-sign-compare.cpp
deleted file mode 100644
index 3042bfde6e06..000000000000
--- a/test/SemaCXX/warn-sign-compare.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -Wsign-compare %s
-
-// NOTE: When a 'enumeral mismatch' warning is implemented then expect several
-// of the following cases to be impacted.
-
-// namespace for anonymous enums tests
-namespace test1 {
- enum { A };
- enum { B = -1 };
-
- template <typename T> struct Foo {
- enum { C };
- enum { D = ~0U };
- };
-
- enum { E = ~0U };
-
- void doit_anonymous( int i ) {
- int a1 = 1 ? i : A;
- int a2 = 1 ? A : i;
-
- int b1 = 1 ? i : B;
- int b2 = 1 ? B : i;
-
- int c1 = 1 ? i : Foo<bool>::C;
- int c2 = 1 ? Foo<bool>::C : i;
-
- int d1 = 1 ? i : Foo<bool>::D; // expected-warning {{operands of ? are integers of different signs}}
- int d2 = 1 ? Foo<bool>::D : i; // expected-warning {{operands of ? are integers of different signs}}
- int d3 = 1 ? B : Foo<bool>::D; // expected-warning {{operands of ? are integers of different signs}}
- int d4 = 1 ? Foo<bool>::D : B; // expected-warning {{operands of ? are integers of different signs}}
-
- int e1 = 1 ? i : E; // expected-warning {{operands of ? are integers of different signs}}
- int e2 = 1 ? E : i; // expected-warning {{operands of ? are integers of different signs}}
- int e3 = 1 ? E : B; // expected-warning {{operands of ? are integers of different signs}}
- int e4 = 1 ? B : E; // expected-warning {{operands of ? are integers of different signs}}
- }
-}
-
-// namespace for named enums tests
-namespace test2 {
- enum Named1 { A };
- enum Named2 { B = -1 };
-
- template <typename T> struct Foo {
- enum Named3 { C };
- enum Named4 { D = ~0U };
- };
-
- enum Named5 { E = ~0U };
-
- void doit_anonymous( int i ) {
- int a1 = 1 ? i : A;
- int a2 = 1 ? A : i;
-
- int b1 = 1 ? i : B;
- int b2 = 1 ? B : i;
-
- int c1 = 1 ? i : Foo<bool>::C;
- int c2 = 1 ? Foo<bool>::C : i;
-
- int d1 = 1 ? i : Foo<bool>::D; // expected-warning {{operands of ? are integers of different signs}}
- int d2 = 1 ? Foo<bool>::D : i; // expected-warning {{operands of ? are integers of different signs}}
- int d3 = 1 ? B : Foo<bool>::D; // expected-warning {{operands of ? are integers of different signs}}
- int d4 = 1 ? Foo<bool>::D : B; // expected-warning {{operands of ? are integers of different signs}}
-
- int e1 = 1 ? i : E; // expected-warning {{operands of ? are integers of different signs}}
- int e2 = 1 ? E : i; // expected-warning {{operands of ? are integers of different signs}}
- int e3 = 1 ? E : B; // expected-warning {{operands of ? are integers of different signs}}
- int e4 = 1 ? B : E; // expected-warning {{operands of ? are integers of different signs}}
- }
-}
diff --git a/test/SemaCXX/warn-sign-conversion.cpp b/test/SemaCXX/warn-sign-conversion.cpp
new file mode 100644
index 000000000000..ba2bc9b3d026
--- /dev/null
+++ b/test/SemaCXX/warn-sign-conversion.cpp
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wsign-conversion %s
+
+// NOTE: When a 'enumeral mismatch' warning is implemented then expect several
+// of the following cases to be impacted.
+
+// namespace for anonymous enums tests
+namespace test1 {
+ enum { A };
+ enum { B = -1 };
+
+ template <typename T> struct Foo {
+ enum { C };
+ enum { D = ~0U };
+ };
+
+ enum { E = ~0U };
+
+ void doit_anonymous( int i ) {
+ int a1 = 1 ? i : A;
+ int a2 = 1 ? A : i;
+
+ int b1 = 1 ? i : B;
+ int b2 = 1 ? B : i;
+
+ int c1 = 1 ? i : Foo<bool>::C;
+ int c2 = 1 ? Foo<bool>::C : i;
+
+ int d1a = 1 ? i : Foo<bool>::D; // expected-warning {{test1::Foo<bool>::<anonymous enum at }}
+ int d1b = 1 ? i : Foo<bool>::D; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
+ int d2a = 1 ? Foo<bool>::D : i; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::<anonymous enum at }}
+ int d2b = 1 ? Foo<bool>::D : i; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
+ int d3a = 1 ? B : Foo<bool>::D; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::<anonymous enum at }}
+ int d3b = 1 ? B : Foo<bool>::D; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
+ int d4a = 1 ? Foo<bool>::D : B; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::<anonymous enum at }}
+ int d4b = 1 ? Foo<bool>::D : B; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
+
+ int e1a = 1 ? i : E; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
+ int e1b = 1 ? i : E; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
+ int e2a = 1 ? E : i; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
+ int e2b = 1 ? E : i; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
+ int e3a = 1 ? E : B; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
+ int e3b = 1 ? E : B; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
+ int e4a = 1 ? B : E; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
+ int e4b = 1 ? B : E; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
+ }
+}
+
+// namespace for named enums tests
+namespace test2 {
+ enum Named1 { A };
+ enum Named2 { B = -1 };
+
+ template <typename T> struct Foo {
+ enum Named3 { C };
+ enum Named4 { D = ~0U };
+ };
+
+ enum Named5 { E = ~0U };
+
+ void doit_anonymous( int i ) {
+ int a1 = 1 ? i : A;
+ int a2 = 1 ? A : i;
+
+ int b1 = 1 ? i : B;
+ int b2 = 1 ? B : i;
+
+ int c1 = 1 ? i : Foo<bool>::C;
+ int c2 = 1 ? Foo<bool>::C : i;
+
+ int d1 = 1 ? i : Foo<bool>::D; // expected-warning {{operand of ? changes signedness: 'test2::Foo<bool>::Named4' to 'int'}}
+ int d2 = 1 ? Foo<bool>::D : i; // expected-warning {{operand of ? changes signedness: 'test2::Foo<bool>::Named4' to 'int'}}
+ int d3 = 1 ? B : Foo<bool>::D; // expected-warning {{operand of ? changes signedness: 'test2::Foo<bool>::Named4' to 'int'}}
+ int d4 = 1 ? Foo<bool>::D : B; // expected-warning {{operand of ? changes signedness: 'test2::Foo<bool>::Named4' to 'int'}}
+
+ int e1 = 1 ? i : E; // expected-warning {{operand of ? changes signedness: 'test2::Named5' to 'int'}}
+ int e2 = 1 ? E : i; // expected-warning {{operand of ? changes signedness: 'test2::Named5' to 'int'}}
+ int e3 = 1 ? E : B; // expected-warning {{operand of ? changes signedness: 'test2::Named5' to 'int'}}
+ int e4 = 1 ? B : E; // expected-warning {{operand of ? changes signedness: 'test2::Named5' to 'int'}}
+ }
+}
diff --git a/test/SemaCXX/warn-string-conversion.cpp b/test/SemaCXX/warn-string-conversion.cpp
new file mode 100644
index 000000000000..23960e48df61
--- /dev/null
+++ b/test/SemaCXX/warn-string-conversion.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -Wstring-conversion -verify %s
+
+// Warn on cases where a string literal is converted into a bool.
+// An exception is made for this in logical operators.
+void assert(bool condition);
+void test0() {
+ bool b0 = "hi"; // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
+ b0 = ""; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
+ b0 = 0 && "";
+ assert("error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
+ assert(0 && "error");
+
+ while("hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
+ do {} while("hi"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
+ for (;"hi";); // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
+ if("hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
+}
+
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
new file mode 100644
index 000000000000..90a8933150ac
--- /dev/null
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -0,0 +1,1422 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
+
+#define LOCKABLE __attribute__ ((lockable))
+#define SCOPED_LOCKABLE __attribute__ ((scoped_lockable))
+#define GUARDED_BY(x) __attribute__ ((guarded_by(x)))
+#define GUARDED_VAR __attribute__ ((guarded_var))
+#define PT_GUARDED_BY(x) __attribute__ ((pt_guarded_by(x)))
+#define PT_GUARDED_VAR __attribute__ ((pt_guarded_var))
+#define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__)))
+#define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__)))
+#define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock_function(__VA_ARGS__)))
+#define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock_function(__VA_ARGS__)))
+#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock_function(__VA_ARGS__)))
+#define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock_function(__VA_ARGS__)))
+#define UNLOCK_FUNCTION(...) __attribute__ ((unlock_function(__VA_ARGS__)))
+#define LOCK_RETURNED(x) __attribute__ ((lock_returned(x)))
+#define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__)))
+#define EXCLUSIVE_LOCKS_REQUIRED(...) \
+ __attribute__ ((exclusive_locks_required(__VA_ARGS__)))
+#define SHARED_LOCKS_REQUIRED(...) \
+ __attribute__ ((shared_locks_required(__VA_ARGS__)))
+#define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis))
+
+//-----------------------------------------//
+// Helper fields
+//-----------------------------------------//
+
+
+class __attribute__((lockable)) Mutex {
+ public:
+ void Lock() __attribute__((exclusive_lock_function));
+ void ReaderLock() __attribute__((shared_lock_function));
+ void Unlock() __attribute__((unlock_function));
+ bool TryLock() __attribute__((exclusive_trylock_function(true)));
+ bool ReaderTryLock() __attribute__((shared_trylock_function(true)));
+ void LockWhen(const int &cond) __attribute__((exclusive_lock_function));
+};
+
+
+Mutex sls_mu;
+
+Mutex sls_mu2 __attribute__((acquired_after(sls_mu)));
+int sls_guard_var __attribute__((guarded_var)) = 0;
+int sls_guardby_var __attribute__((guarded_by(sls_mu))) = 0;
+
+bool getBool();
+
+class MutexWrapper {
+public:
+ Mutex mu;
+ int x __attribute__((guarded_by(mu)));
+ void MyLock() __attribute__((exclusive_lock_function(mu)));
+};
+
+MutexWrapper sls_mw;
+
+void sls_fun_0() {
+ sls_mw.mu.Lock();
+ sls_mw.x = 5;
+ sls_mw.mu.Unlock();
+}
+
+void sls_fun_2() {
+ sls_mu.Lock();
+ int x = sls_guard_var;
+ sls_mu.Unlock();
+}
+
+void sls_fun_3() {
+ sls_mu.Lock();
+ sls_guard_var = 2;
+ sls_mu.Unlock();
+}
+
+void sls_fun_4() {
+ sls_mu2.Lock();
+ sls_guard_var = 2;
+ sls_mu2.Unlock();
+}
+
+void sls_fun_5() {
+ sls_mu.Lock();
+ int x = sls_guardby_var;
+ sls_mu.Unlock();
+}
+
+void sls_fun_6() {
+ sls_mu.Lock();
+ sls_guardby_var = 2;
+ sls_mu.Unlock();
+}
+
+void sls_fun_7() {
+ sls_mu.Lock();
+ sls_mu2.Lock();
+ sls_mu2.Unlock();
+ sls_mu.Unlock();
+}
+
+void sls_fun_8() {
+ sls_mu.Lock();
+ if (getBool())
+ sls_mu.Unlock();
+ else
+ sls_mu.Unlock();
+}
+
+void sls_fun_9() {
+ if (getBool())
+ sls_mu.Lock();
+ else
+ sls_mu.Lock();
+ sls_mu.Unlock();
+}
+
+void sls_fun_good_6() {
+ if (getBool()) {
+ sls_mu.Lock();
+ } else {
+ if (getBool()) {
+ getBool(); // EMPTY
+ } else {
+ getBool(); // EMPTY
+ }
+ sls_mu.Lock();
+ }
+ sls_mu.Unlock();
+}
+
+void sls_fun_good_7() {
+ sls_mu.Lock();
+ while (getBool()) {
+ sls_mu.Unlock();
+ if (getBool()) {
+ if (getBool()) {
+ sls_mu.Lock();
+ continue;
+ }
+ }
+ sls_mu.Lock();
+ }
+ sls_mu.Unlock();
+}
+
+void sls_fun_good_8() {
+ sls_mw.MyLock();
+ sls_mw.mu.Unlock();
+}
+
+void sls_fun_bad_1() {
+ sls_mu.Unlock(); // \
+ // expected-warning{{unlocking 'sls_mu' that was not locked}}
+}
+
+void sls_fun_bad_2() {
+ sls_mu.Lock();
+ sls_mu.Lock(); // \
+ // expected-warning{{locking 'sls_mu' that is already locked}}
+ sls_mu.Unlock();
+}
+
+void sls_fun_bad_3() {
+ sls_mu.Lock(); // \
+ // expected-warning{{mutex 'sls_mu' is still locked at the end of function 'sls_fun_bad_3'}}
+}
+
+void sls_fun_bad_4() {
+ if (getBool())
+ sls_mu.Lock(); // \
+ // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}}
+ else
+ sls_mu2.Lock(); // \
+ // expected-warning{{mutex 'sls_mu2' is still locked at the end of its scope}}
+}
+
+void sls_fun_bad_5() {
+ sls_mu.Lock(); // \
+ // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}}
+ if (getBool())
+ sls_mu.Unlock();
+}
+
+void sls_fun_bad_6() {
+ if (getBool()) {
+ sls_mu.Lock(); // \
+ // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}}
+ } else {
+ if (getBool()) {
+ getBool(); // EMPTY
+ } else {
+ getBool(); // EMPTY
+ }
+ }
+ sls_mu.Unlock(); // \
+ // expected-warning{{unlocking 'sls_mu' that was not locked}}
+}
+
+void sls_fun_bad_7() {
+ sls_mu.Lock(); // \
+ // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ while (getBool()) {
+ sls_mu.Unlock();
+ if (getBool()) {
+ if (getBool()) {
+ continue;
+ }
+ }
+ sls_mu.Lock(); // \
+ // expected-warning{{mutex 'sls_mu' is still locked at the end of its scope}}
+ }
+ sls_mu.Unlock();
+}
+
+void sls_fun_bad_8() {
+ sls_mu.Lock(); // \
+ // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ do {
+ sls_mu.Unlock();
+ } while (getBool());
+}
+
+void sls_fun_bad_9() {
+ do {
+ sls_mu.Lock(); // \
+ // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ } while (getBool());
+ sls_mu.Unlock();
+}
+
+void sls_fun_bad_10() {
+ sls_mu.Lock(); // \
+ // expected-warning{{mutex 'sls_mu' is still locked at the end of function 'sls_fun_bad_10'}} \
+ // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ while(getBool()) {
+ sls_mu.Unlock();
+ }
+}
+
+void sls_fun_bad_11() {
+ while (getBool()) {
+ sls_mu.Lock(); // \
+ // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ }
+ sls_mu.Unlock(); // \
+ // expected-warning{{unlocking 'sls_mu' that was not locked}}
+}
+
+//-----------------------------------------//
+// Handling lock expressions in attribute args
+// -------------------------------------------//
+
+Mutex aa_mu;
+
+class GlobalLocker {
+public:
+ void globalLock() __attribute__((exclusive_lock_function(aa_mu)));
+ void globalUnlock() __attribute__((unlock_function(aa_mu)));
+};
+
+GlobalLocker glock;
+
+void aa_fun_1() {
+ glock.globalLock();
+ glock.globalUnlock();
+}
+
+void aa_fun_bad_1() {
+ glock.globalUnlock(); // \
+ // expected-warning{{unlocking 'aa_mu' that was not locked}}
+}
+
+void aa_fun_bad_2() {
+ glock.globalLock();
+ glock.globalLock(); // \
+ // expected-warning{{locking 'aa_mu' that is already locked}}
+ glock.globalUnlock();
+}
+
+void aa_fun_bad_3() {
+ glock.globalLock(); // \
+ // expected-warning{{mutex 'aa_mu' is still locked at the end of function 'aa_fun_bad_3'}}
+}
+
+//--------------------------------------------------//
+// Regression tests for unusual method names
+//--------------------------------------------------//
+
+Mutex wmu;
+
+// Test diagnostics for other method names.
+class WeirdMethods {
+ WeirdMethods() {
+ wmu.Lock(); // \
+ // expected-warning {{mutex 'wmu' is still locked at the end of function 'WeirdMethods'}}
+ }
+ ~WeirdMethods() {
+ wmu.Lock(); // \
+ // expected-warning {{mutex 'wmu' is still locked at the end of function '~WeirdMethods'}}
+ }
+ void operator++() {
+ wmu.Lock(); // \
+ // expected-warning {{mutex 'wmu' is still locked at the end of function 'operator++'}}
+ }
+ operator int*() {
+ wmu.Lock(); // \
+ // expected-warning {{mutex 'wmu' is still locked at the end of function 'operator int *'}}
+ return 0;
+ }
+};
+
+//-----------------------------------------------//
+// Errors for guarded by or guarded var variables
+// ----------------------------------------------//
+
+int *pgb_gvar __attribute__((pt_guarded_var));
+int *pgb_var __attribute__((pt_guarded_by(sls_mu)));
+
+class PGBFoo {
+ public:
+ int x;
+ int *pgb_field __attribute__((guarded_by(sls_mu2)))
+ __attribute__((pt_guarded_by(sls_mu)));
+ void testFoo() {
+ pgb_field = &x; // \
+ // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
+ *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
+ // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
+ x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
+ // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
+ (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
+ // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
+ }
+};
+
+class GBFoo {
+ public:
+ int gb_field __attribute__((guarded_by(sls_mu)));
+
+ void testFoo() {
+ gb_field = 0; // \
+ // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
+ }
+
+ void testNoAnal() __attribute__((no_thread_safety_analysis)) {
+ gb_field = 0;
+ }
+};
+
+GBFoo GlobalGBFoo __attribute__((guarded_by(sls_mu)));
+
+void gb_fun_0() {
+ sls_mu.Lock();
+ int x = *pgb_var;
+ sls_mu.Unlock();
+}
+
+void gb_fun_1() {
+ sls_mu.Lock();
+ *pgb_var = 2;
+ sls_mu.Unlock();
+}
+
+void gb_fun_2() {
+ int x;
+ pgb_var = &x;
+}
+
+void gb_fun_3() {
+ int *x = pgb_var;
+}
+
+void gb_bad_0() {
+ sls_guard_var = 1; // \
+ // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+}
+
+void gb_bad_1() {
+ int x = sls_guard_var; // \
+ // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
+}
+
+void gb_bad_2() {
+ sls_guardby_var = 1; // \
+ // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
+}
+
+void gb_bad_3() {
+ int x = sls_guardby_var; // \
+ // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
+}
+
+void gb_bad_4() {
+ *pgb_gvar = 1; // \
+ // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
+}
+
+void gb_bad_5() {
+ int x = *pgb_gvar; // \
+ // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
+}
+
+void gb_bad_6() {
+ *pgb_var = 1; // \
+ // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
+}
+
+void gb_bad_7() {
+ int x = *pgb_var; // \
+ // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
+}
+
+void gb_bad_8() {
+ GBFoo G;
+ G.gb_field = 0; // \
+ // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
+}
+
+void gb_bad_9() {
+ sls_guard_var++; // \
+ // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ sls_guard_var--; // \
+ // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ ++sls_guard_var; // \
+ // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ --sls_guard_var;// \
+ // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+}
+
+//-----------------------------------------------//
+// Warnings on variables with late parsed attributes
+// ----------------------------------------------//
+
+class LateFoo {
+public:
+ int a __attribute__((guarded_by(mu)));
+ int b;
+
+ void foo() __attribute__((exclusive_locks_required(mu))) { }
+
+ void test() {
+ a = 0; // \
+ // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ b = a; // \
+ // expected-warning {{reading variable 'a' requires locking 'mu'}}
+ c = 0; // \
+ // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
+ }
+
+ int c __attribute__((guarded_by(mu)));
+
+ Mutex mu;
+};
+
+class LateBar {
+ public:
+ int a_ __attribute__((guarded_by(mu1_)));
+ int b_;
+ int *q __attribute__((pt_guarded_by(mu)));
+ Mutex mu1_;
+ Mutex mu;
+ LateFoo Foo;
+ LateFoo Foo2;
+ LateFoo *FooPointer;
+};
+
+LateBar b1, *b3;
+
+void late_0() {
+ LateFoo FooA;
+ LateFoo FooB;
+ FooA.mu.Lock();
+ FooA.a = 5;
+ FooA.mu.Unlock();
+}
+
+void late_1() {
+ LateBar BarA;
+ BarA.FooPointer->mu.Lock();
+ BarA.FooPointer->a = 2;
+ BarA.FooPointer->mu.Unlock();
+}
+
+void late_bad_0() {
+ LateFoo fooA;
+ LateFoo fooB;
+ fooA.mu.Lock();
+ fooB.a = 5; // \
+ // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ fooA.mu.Unlock();
+}
+
+void late_bad_1() {
+ Mutex mu;
+ mu.Lock();
+ 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'}}
+ b1.mu1_.Unlock();
+ b1.b_ = res;
+ mu.Unlock();
+}
+
+void late_bad_2() {
+ LateBar BarA;
+ BarA.FooPointer->mu.Lock();
+ BarA.Foo.a = 2; // \
+ // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ BarA.FooPointer->mu.Unlock();
+}
+
+void late_bad_3() {
+ LateBar BarA;
+ BarA.Foo.mu.Lock();
+ BarA.FooPointer->a = 2; // \
+ // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ BarA.Foo.mu.Unlock();
+}
+
+void late_bad_4() {
+ LateBar BarA;
+ BarA.Foo.mu.Lock();
+ BarA.Foo2.a = 2; // \
+ // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ BarA.Foo.mu.Unlock();
+}
+
+//-----------------------------------------------//
+// Extra warnings for shared vs. exclusive locks
+// ----------------------------------------------//
+
+void shared_fun_0() {
+ sls_mu.Lock();
+ do {
+ sls_mu.Unlock();
+ sls_mu.Lock();
+ } while (getBool());
+ sls_mu.Unlock();
+}
+
+void shared_fun_1() {
+ sls_mu.ReaderLock(); // \
+ // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ do {
+ sls_mu.Unlock();
+ sls_mu.Lock(); // \
+ // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ } while (getBool());
+ sls_mu.Unlock();
+}
+
+void shared_fun_3() {
+ if (getBool())
+ sls_mu.Lock();
+ else
+ sls_mu.Lock();
+ *pgb_var = 1;
+ sls_mu.Unlock();
+}
+
+void shared_fun_4() {
+ if (getBool())
+ sls_mu.ReaderLock();
+ else
+ sls_mu.ReaderLock();
+ int x = sls_guardby_var;
+ sls_mu.Unlock();
+}
+
+void shared_fun_8() {
+ if (getBool())
+ sls_mu.Lock(); // \
+ // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ else
+ sls_mu.ReaderLock(); // \
+ // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ sls_mu.Unlock();
+}
+
+void shared_bad_0() {
+ sls_mu.Lock(); // \
+ // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ do {
+ sls_mu.Unlock();
+ sls_mu.ReaderLock(); // \
+ // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ } while (getBool());
+ sls_mu.Unlock();
+}
+
+void shared_bad_1() {
+ if (getBool())
+ sls_mu.Lock(); // \
+ // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ else
+ sls_mu.ReaderLock(); // \
+ // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ *pgb_var = 1;
+ sls_mu.Unlock();
+}
+
+void shared_bad_2() {
+ if (getBool())
+ sls_mu.ReaderLock(); // \
+ // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ else
+ sls_mu.Lock(); // \
+ // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ *pgb_var = 1;
+ sls_mu.Unlock();
+}
+
+// FIXME: Add support for functions (not only methods)
+class LRBar {
+ public:
+ void aa_elr_fun() __attribute__((exclusive_locks_required(aa_mu)));
+ void aa_elr_fun_s() __attribute__((shared_locks_required(aa_mu)));
+ void le_fun() __attribute__((locks_excluded(sls_mu)));
+};
+
+class LRFoo {
+ public:
+ void test() __attribute__((exclusive_locks_required(sls_mu)));
+ void testShared() __attribute__((shared_locks_required(sls_mu2)));
+};
+
+void elr_fun() __attribute__((exclusive_locks_required(sls_mu)));
+void elr_fun() {}
+
+LRFoo MyLRFoo;
+LRBar Bar;
+
+void es_fun_0() {
+ aa_mu.Lock();
+ Bar.aa_elr_fun();
+ aa_mu.Unlock();
+}
+
+void es_fun_1() {
+ aa_mu.Lock();
+ Bar.aa_elr_fun_s();
+ aa_mu.Unlock();
+}
+
+void es_fun_2() {
+ aa_mu.ReaderLock();
+ Bar.aa_elr_fun_s();
+ aa_mu.Unlock();
+}
+
+void es_fun_3() {
+ sls_mu.Lock();
+ MyLRFoo.test();
+ sls_mu.Unlock();
+}
+
+void es_fun_4() {
+ sls_mu2.Lock();
+ MyLRFoo.testShared();
+ sls_mu2.Unlock();
+}
+
+void es_fun_5() {
+ sls_mu2.ReaderLock();
+ MyLRFoo.testShared();
+ sls_mu2.Unlock();
+}
+
+void es_fun_6() {
+ Bar.le_fun();
+}
+
+void es_fun_7() {
+ sls_mu.Lock();
+ elr_fun();
+ sls_mu.Unlock();
+}
+
+void es_fun_8() __attribute__((no_thread_safety_analysis));
+
+void es_fun_8() {
+ Bar.aa_elr_fun_s();
+}
+
+void es_fun_9() __attribute__((shared_locks_required(aa_mu)));
+void es_fun_9() {
+ Bar.aa_elr_fun_s();
+}
+
+void es_fun_10() __attribute__((exclusive_locks_required(aa_mu)));
+void es_fun_10() {
+ Bar.aa_elr_fun_s();
+}
+
+void es_bad_0() {
+ Bar.aa_elr_fun(); // \
+ // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
+}
+
+void es_bad_1() {
+ aa_mu.ReaderLock();
+ Bar.aa_elr_fun(); // \
+ // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
+ aa_mu.Unlock();
+}
+
+void es_bad_2() {
+ Bar.aa_elr_fun_s(); // \
+ // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
+}
+
+void es_bad_3() {
+ MyLRFoo.test(); // \
+ // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
+}
+
+void es_bad_4() {
+ MyLRFoo.testShared(); // \
+ // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
+}
+
+void es_bad_5() {
+ sls_mu.ReaderLock();
+ MyLRFoo.test(); // \
+ // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
+ sls_mu.Unlock();
+}
+
+void es_bad_6() {
+ sls_mu.Lock();
+ Bar.le_fun(); // \
+ // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
+ sls_mu.Unlock();
+}
+
+void es_bad_7() {
+ sls_mu.ReaderLock();
+ Bar.le_fun(); // \
+ // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
+ sls_mu.Unlock();
+}
+
+//-----------------------------------------------//
+// Unparseable lock expressions
+// ----------------------------------------------//
+
+Mutex UPmu;
+// FIXME: add support for lock expressions involving arrays.
+Mutex mua[5];
+
+int x __attribute__((guarded_by(UPmu = sls_mu))); // \
+ // expected-warning{{cannot resolve lock expression to a specific lockable object}}
+int y __attribute__((guarded_by(mua[0]))); // \
+ // expected-warning{{cannot resolve lock expression to a specific lockable object}}
+
+
+void testUnparse() {
+ // no errors, since the lock expressions are not resolved
+ x = 5;
+ y = 5;
+}
+
+void testUnparse2() {
+ mua[0].Lock(); // \
+ // expected-warning{{cannot resolve lock expression to a specific lockable object}}
+ (&(mua[0]) + 4)->Lock(); // \
+ // expected-warning{{cannot resolve lock expression to a specific lockable object}}
+}
+
+
+//----------------------------------------------------------------------------//
+// The following test cases are ported from the gcc thread safety implementation
+// They are each wrapped inside a namespace with the test number of the gcc test
+//
+// FIXME: add all the gcc tests, once this analysis passes them.
+//----------------------------------------------------------------------------//
+
+//-----------------------------------------//
+// Good testcases (no errors)
+//-----------------------------------------//
+
+namespace thread_annot_lock_20 {
+class Bar {
+ public:
+ static int func1() EXCLUSIVE_LOCKS_REQUIRED(mu1_);
+ static int b_ GUARDED_BY(mu1_);
+ static Mutex mu1_;
+ static int a_ GUARDED_BY(mu1_);
+};
+
+Bar b1;
+
+int Bar::func1()
+{
+ int res = 5;
+
+ if (a_ == 4)
+ res = b_;
+ return res;
+}
+} // end namespace thread_annot_lock_20
+
+namespace thread_annot_lock_22 {
+// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
+// uses in class definitions.
+Mutex mu;
+
+class Bar {
+ public:
+ int a_ GUARDED_BY(mu1_);
+ int b_;
+ int *q PT_GUARDED_BY(mu);
+ Mutex mu1_ ACQUIRED_AFTER(mu);
+};
+
+Bar b1, *b3;
+int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
+int res GUARDED_BY(mu) = 5;
+
+int func(int i)
+{
+ int x;
+ mu.Lock();
+ b1.mu1_.Lock();
+ res = b1.a_ + b3->b_;
+ *p = i;
+ b1.a_ = res + b3->b_;
+ b3->b_ = *b1.q;
+ b1.mu1_.Unlock();
+ b1.b_ = res;
+ x = res;
+ mu.Unlock();
+ return x;
+}
+} // end namespace thread_annot_lock_22
+
+namespace thread_annot_lock_27_modified {
+// test lock annotations applied to function definitions
+// Modified: applied annotations only to function declarations
+Mutex mu1;
+Mutex mu2 ACQUIRED_AFTER(mu1);
+
+class Foo {
+ public:
+ int method1(int i) SHARED_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1);
+};
+
+int Foo::method1(int i) {
+ return i;
+}
+
+
+int foo(int i) EXCLUSIVE_LOCKS_REQUIRED(mu2) SHARED_LOCKS_REQUIRED(mu1);
+int foo(int i) {
+ return i;
+}
+
+static int bar(int i) EXCLUSIVE_LOCKS_REQUIRED(mu1);
+static int bar(int i) {
+ return i;
+}
+
+void main() {
+ Foo a;
+
+ mu1.Lock();
+ mu2.Lock();
+ a.method1(1);
+ foo(2);
+ mu2.Unlock();
+ bar(3);
+ mu1.Unlock();
+}
+} // end namespace thread_annot_lock_27_modified
+
+
+namespace thread_annot_lock_38 {
+// Test the case where a template member function is annotated with lock
+// attributes in a non-template class.
+class Foo {
+ public:
+ void func1(int y) LOCKS_EXCLUDED(mu_);
+ template <typename T> void func2(T x) LOCKS_EXCLUDED(mu_);
+ private:
+ Mutex mu_;
+};
+
+Foo *foo;
+
+void main()
+{
+ foo->func1(5);
+ foo->func2(5);
+}
+} // end namespace thread_annot_lock_38
+
+namespace thread_annot_lock_43 {
+// Tests lock canonicalization
+class Foo {
+ public:
+ Mutex *mu_;
+};
+
+class FooBar {
+ public:
+ Foo *foo_;
+ int GetA() EXCLUSIVE_LOCKS_REQUIRED(foo_->mu_) { return a_; }
+ int a_ GUARDED_BY(foo_->mu_);
+};
+
+FooBar *fb;
+
+void main()
+{
+ int x;
+ fb->foo_->mu_->Lock();
+ x = fb->GetA();
+ fb->foo_->mu_->Unlock();
+}
+} // end namespace thread_annot_lock_43
+
+namespace thread_annot_lock_49 {
+// Test the support for use of lock expression in the annotations
+class Foo {
+ public:
+ Mutex foo_mu_;
+};
+
+class Bar {
+ private:
+ Foo *foo;
+ Mutex bar_mu_ ACQUIRED_AFTER(foo->foo_mu_);
+
+ public:
+ void Test1() {
+ foo->foo_mu_.Lock();
+ bar_mu_.Lock();
+ bar_mu_.Unlock();
+ foo->foo_mu_.Unlock();
+ }
+};
+
+void main() {
+ Bar bar;
+ bar.Test1();
+}
+} // end namespace thread_annot_lock_49
+
+namespace thread_annot_lock_61_modified {
+ // Modified to fix the compiler errors
+ // Test the fix for a bug introduced by the support of pass-by-reference
+ // paramters.
+ struct Foo { Foo &operator<< (bool) {return *this;} };
+ Foo &getFoo();
+ struct Bar { Foo &func () {return getFoo();} };
+ struct Bas { void operator& (Foo &) {} };
+ void mumble()
+ {
+ Bas() & Bar().func() << "" << "";
+ Bas() & Bar().func() << "";
+ }
+} // end namespace thread_annot_lock_61_modified
+
+
+namespace thread_annot_lock_65 {
+// Test the fix for a bug in the support of allowing reader locks for
+// non-const, non-modifying overload functions. (We didn't handle the builtin
+// properly.)
+enum MyFlags {
+ Zero,
+ One,
+ Two,
+ Three,
+ Four,
+ Five,
+ Six,
+ Seven,
+ Eight,
+ Nine
+};
+
+inline MyFlags
+operator|(MyFlags a, MyFlags b)
+{
+ return MyFlags(static_cast<int>(a) | static_cast<int>(b));
+}
+
+inline MyFlags&
+operator|=(MyFlags& a, MyFlags b)
+{
+ return a = a | b;
+}
+} // end namespace thread_annot_lock_65
+
+namespace thread_annot_lock_66_modified {
+// Modified: Moved annotation to function defn
+// Test annotations on out-of-line definitions of member functions where the
+// annotations refer to locks that are also data members in the class.
+Mutex mu;
+
+class Foo {
+ public:
+ int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2);
+ int data GUARDED_BY(mu1);
+ Mutex *mu1;
+ Mutex *mu2;
+};
+
+int Foo::method1(int i)
+{
+ return data + i;
+}
+
+void main()
+{
+ Foo a;
+
+ a.mu2->Lock();
+ a.mu1->Lock();
+ mu.Lock();
+ a.method1(1);
+ mu.Unlock();
+ a.mu1->Unlock();
+ a.mu2->Unlock();
+}
+} // end namespace thread_annot_lock_66_modified
+
+namespace thread_annot_lock_68_modified {
+// Test a fix to a bug in the delayed name binding with nested template
+// instantiation. We use a stack to make sure a name is not resolved to an
+// inner context.
+template <typename T>
+class Bar {
+ Mutex mu_;
+};
+
+template <typename T>
+class Foo {
+ public:
+ void func(T x) {
+ mu_.Lock();
+ count_ = x;
+ mu_.Unlock();
+ }
+
+ private:
+ T count_ GUARDED_BY(mu_);
+ Bar<T> bar_;
+ Mutex mu_;
+};
+
+void main()
+{
+ Foo<int> *foo;
+ foo->func(5);
+}
+} // end namespace thread_annot_lock_68_modified
+
+namespace thread_annot_lock_30_modified {
+// Test delay parsing of lock attribute arguments with nested classes.
+// Modified: trylocks replaced with exclusive_lock_fun
+int a = 0;
+
+class Bar {
+ struct Foo;
+
+ public:
+ void MyLock() EXCLUSIVE_LOCK_FUNCTION(mu);
+
+ int func() {
+ MyLock();
+// if (foo == 0) {
+// return 0;
+// }
+ a = 5;
+ mu.Unlock();
+ return 1;
+ }
+
+ class FooBar {
+ int x;
+ int y;
+ };
+
+ private:
+ Mutex mu;
+};
+
+Bar *bar;
+
+void main()
+{
+ bar->func();
+}
+} // end namespace thread_annot_lock_30_modified
+
+namespace thread_annot_lock_47 {
+// Test the support for annotations on virtual functions.
+// This is a good test case. (i.e. There should be no warning emitted by the
+// compiler.)
+class Base {
+ public:
+ virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+ virtual void func2() LOCKS_EXCLUDED(mu_);
+ Mutex mu_;
+};
+
+class Child : public Base {
+ public:
+ virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+ virtual void func2() LOCKS_EXCLUDED(mu_);
+};
+
+void main() {
+ Child *c;
+ Base *b = c;
+
+ b->mu_.Lock();
+ b->func1();
+ b->mu_.Unlock();
+ b->func2();
+
+ c->mu_.Lock();
+ c->func1();
+ c->mu_.Unlock();
+ c->func2();
+}
+} // end namespace thread_annot_lock_47
+
+//-----------------------------------------//
+// Tests which produce errors
+//-----------------------------------------//
+
+namespace thread_annot_lock_13 {
+Mutex mu1;
+Mutex mu2;
+
+int g GUARDED_BY(mu1);
+int w GUARDED_BY(mu2);
+
+class Foo {
+ public:
+ void bar() LOCKS_EXCLUDED(mu_, mu1);
+ int foo() SHARED_LOCKS_REQUIRED(mu_) EXCLUSIVE_LOCKS_REQUIRED(mu2);
+
+ private:
+ int a_ GUARDED_BY(mu_);
+ public:
+ Mutex mu_ ACQUIRED_AFTER(mu1);
+};
+
+int Foo::foo()
+{
+ int res;
+ w = 5.2;
+ res = a_ + 5;
+ return res;
+}
+
+void Foo::bar()
+{
+ int x;
+ mu_.Lock();
+ x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
+ a_ = x + 1;
+ mu_.Unlock();
+ if (x > 5) {
+ mu1.Lock();
+ g = 2.3;
+ mu1.Unlock();
+ }
+}
+
+void main()
+{
+ Foo f1, *f2;
+ f1.mu_.Lock();
+ f1.bar(); // expected-warning {{cannot call function 'bar' while mutex '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->mu_.Unlock();
+ mu2.Lock();
+ w = 2.5;
+ mu2.Unlock();
+}
+} // end namespace thread_annot_lock_13
+
+namespace thread_annot_lock_18_modified {
+// Modified: Trylocks removed
+// Test the ability to distnguish between the same lock field of
+// different objects of a class.
+ class Bar {
+ public:
+ bool MyLock() EXCLUSIVE_LOCK_FUNCTION(mu1_);
+ void MyUnlock() UNLOCK_FUNCTION(mu1_);
+ int a_ GUARDED_BY(mu1_);
+
+ private:
+ Mutex mu1_;
+};
+
+Bar *b1, *b2;
+
+void func()
+{
+ b1->MyLock();
+ b1->a_ = 5;
+ b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
+ b2->MyLock();
+ b2->MyUnlock();
+ b1->MyUnlock();
+}
+} // end namespace thread_annot_lock_18_modified
+
+namespace thread_annot_lock_21 {
+// Test various usage of GUARDED_BY and PT_GUARDED_BY annotations, especially
+// uses in class definitions.
+Mutex mu;
+
+class Bar {
+ public:
+ int a_ GUARDED_BY(mu1_);
+ int b_;
+ int *q PT_GUARDED_BY(mu);
+ Mutex mu1_ ACQUIRED_AFTER(mu);
+};
+
+Bar b1, *b3;
+int *p GUARDED_BY(mu) PT_GUARDED_BY(mu);
+
+int res GUARDED_BY(mu) = 5;
+
+int func(int i)
+{
+ int x;
+ b3->mu1_.Lock();
+ res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking '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}}
+ 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'}}
+ x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
+ return x;
+}
+} // end namespace thread_annot_lock_21
+
+namespace thread_annot_lock_35_modified {
+// Test the analyzer's ability to distinguish the lock field of different
+// objects.
+class Foo {
+ private:
+ Mutex lock_;
+ int a_ GUARDED_BY(lock_);
+
+ public:
+ void Func(Foo* child) LOCKS_EXCLUDED(lock_) {
+ Foo *new_foo = new Foo;
+
+ lock_.Lock();
+
+ 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}}
+ lock_.Unlock();
+ }
+
+ void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_) {
+ a_ = y;
+ }
+};
+
+Foo *x;
+
+void main() {
+ Foo *child = new Foo;
+ x->Func(child);
+}
+} // end namespace thread_annot_lock_35_modified
+
+namespace thread_annot_lock_36_modified {
+// Modified to move the annotations to function defns.
+// Test the analyzer's ability to distinguish the lock field of different
+// objects
+class Foo {
+ private:
+ Mutex lock_;
+ int a_ GUARDED_BY(lock_);
+
+ public:
+ void Func(Foo* child) LOCKS_EXCLUDED(lock_);
+ void bar(int y) EXCLUSIVE_LOCKS_REQUIRED(lock_);
+};
+
+void Foo::Func(Foo* child) {
+ Foo *new_foo = new Foo;
+
+ lock_.Lock();
+
+ child->lock_.Lock();
+ child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'lock_' is locked}}
+ child->bar(7);
+ child->a_ = 5;
+ child->lock_.Unlock();
+
+ lock_.Unlock();
+}
+
+void Foo::bar(int y) {
+ a_ = y;
+}
+
+
+Foo *x;
+
+void main() {
+ Foo *child = new Foo;
+ x->Func(child);
+}
+} // end namespace thread_annot_lock_36_modified
+
+
+namespace thread_annot_lock_42 {
+// Test support of multiple lock attributes of the same kind on a decl.
+class Foo {
+ private:
+ Mutex mu1, mu2, mu3;
+ int x GUARDED_BY(mu1) GUARDED_BY(mu2);
+ int y GUARDED_BY(mu2);
+
+ void f2() LOCKS_EXCLUDED(mu1) LOCKS_EXCLUDED(mu2) LOCKS_EXCLUDED(mu3) {
+ mu2.Lock();
+ y = 2;
+ mu2.Unlock();
+ }
+
+ public:
+ void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
+ x = 5;
+ f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
+ // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
+ }
+};
+
+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'}}
+}
+} // end namespace thread_annot_lock_42
+
+namespace thread_annot_lock_46 {
+// Test the support for annotations on virtual functions.
+class Base {
+ public:
+ virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+ virtual void func2() LOCKS_EXCLUDED(mu_);
+ Mutex mu_;
+};
+
+class Child : public Base {
+ public:
+ virtual void func1() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+ virtual void func2() LOCKS_EXCLUDED(mu_);
+};
+
+void main() {
+ Child *c;
+ Base *b = c;
+
+ b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
+ b->mu_.Lock();
+ b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
+ b->mu_.Unlock();
+
+ c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
+ c->mu_.Lock();
+ c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
+ c->mu_.Unlock();
+}
+} // end namespace thread_annot_lock_46
+
+namespace thread_annot_lock_67_modified {
+// Modified: attributes on definitions moved to declarations
+// Test annotations on out-of-line definitions of member functions where the
+// annotations refer to locks that are also data members in the class.
+Mutex mu;
+Mutex mu3;
+
+class Foo {
+ public:
+ int method1(int i) SHARED_LOCKS_REQUIRED(mu1, mu, mu2, mu3);
+ int data GUARDED_BY(mu1);
+ Mutex *mu1;
+ Mutex *mu2;
+};
+
+int Foo::method1(int i) {
+ return data + i;
+}
+
+void main()
+{
+ Foo a;
+ a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on '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 'mu3'}}
+}
+} // end namespace thread_annot_lock_67_modified
+
+
diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp
new file mode 100644
index 000000000000..67882d08996e
--- /dev/null
+++ b/test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -0,0 +1,1255 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
+
+
+//-----------------------------------------//
+// Helper fields
+//-----------------------------------------//
+
+class __attribute__((lockable)) Mu {
+ public:
+ void Lock();
+};
+
+class UnlockableMu{
+};
+
+class MuWrapper {
+ public:
+ Mu mu;
+ Mu getMu() {
+ return mu;
+ }
+ Mu * getMuPointer() {
+ return &mu;
+ }
+};
+
+
+class MuDoubleWrapper {
+ public:
+ MuWrapper* muWrapper;
+ MuWrapper* getWrapper() {
+ return muWrapper;
+ }
+};
+
+Mu mu1;
+UnlockableMu umu;
+Mu mu2;
+MuWrapper muWrapper;
+MuDoubleWrapper muDoubleWrapper;
+Mu* muPointer;
+Mu ** muDoublePointer = & muPointer;
+Mu& muRef = mu1;
+
+//---------------------------------------//
+// Scoping tests
+//--------------------------------------//
+
+class Foo {
+ Mu foomu;
+ void needLock() __attribute__((exclusive_lock_function(foomu)));
+};
+
+class Foo2 {
+ void needLock() __attribute__((exclusive_lock_function(foomu)));
+ Mu foomu;
+};
+
+class Bar {
+ Mu barmu;
+ Mu barmu2 __attribute__((acquired_after(barmu)));
+};
+
+
+//-----------------------------------------//
+// No Thread Safety Analysis (noanal) //
+//-----------------------------------------//
+
+// FIXME: Right now we cannot parse attributes put on function definitions
+// We would like to patch this at some point.
+
+#if !__has_attribute(no_thread_safety_analysis)
+#error "Should support no_thread_safety_analysis attribute"
+#endif
+
+void noanal_fun() __attribute__((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) {
+ int x __attribute__((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)); // \
+ // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+
+class NoanalFoo {
+ private:
+ int test_field __attribute__((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));
+};
+
+class __attribute__((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))); // \
+ // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+
+
+//-----------------------------------------//
+// Guarded Var Attribute (gv)
+//-----------------------------------------//
+
+#if !__has_attribute(guarded_var)
+#error "Should support guarded_var attribute"
+#endif
+
+int gv_var_noargs __attribute__((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_args __attribute__((guarded_var(1))); // \
+ // expected-error {{attribute takes no arguments}}
+};
+
+class __attribute__((guarded_var)) GV { // \
+ // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+};
+
+void gv_function() __attribute__((guarded_var)); // \
+ // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+
+void gv_function_params(int gv_lvar __attribute__((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; // \
+ // expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
+ return x;
+}
+
+//-----------------------------------------//
+// Pt Guarded Var Attribute (pgv)
+//-----------------------------------------//
+
+//FIXME: add support for boost::scoped_ptr<int> fancyptr and references
+
+#if !__has_attribute(pt_guarded_var)
+#error "Should support pt_guarded_var attribute"
+#endif
+
+int *pgv_pt_var_noargs __attribute__((pt_guarded_var));
+
+int pgv_var_noargs __attribute__((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)); // \
+ // 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 { // \
+ // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+};
+
+int *pgv_var_args __attribute__((pt_guarded_var(1))); // \
+ // expected-error {{attribute takes no arguments}}
+
+
+void pgv_function() __attribute__((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))); // \
+ // 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); // \
+ // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+ delete x;
+}
+
+//-----------------------------------------//
+// Lockable Attribute (l)
+//-----------------------------------------//
+
+//FIXME: In future we may want to add support for structs, ObjC classes, etc.
+
+#if !__has_attribute(lockable)
+#error "Should support lockable attribute"
+#endif
+
+class __attribute__((lockable)) LTestClass {
+};
+
+class __attribute__((lockable (1))) LTestClass_args { // \
+ // expected-error {{attribute takes no arguments}}
+};
+
+void l_test_function() __attribute__((lockable)); // \
+ // expected-warning {{'lockable' attribute only applies to classes}}
+
+int l_testfn(int y) {
+ int x __attribute__((lockable)) = y; // \
+ // expected-warning {{'lockable' attribute only applies to classes}}
+ return x;
+}
+
+int l_test_var __attribute__((lockable)); // \
+ // expected-warning {{'lockable' attribute only applies to classes}}
+
+class LFoo {
+ private:
+ int test_field __attribute__((lockable)); // \
+ // expected-warning {{'lockable' attribute only applies to classes}}
+ void test_method() __attribute__((lockable)); // \
+ // expected-warning {{'lockable' attribute only applies to classes}}
+};
+
+
+void l_function_params(int lvar __attribute__((lockable))); // \
+ // expected-warning {{'lockable' attribute only applies to classes}}
+
+
+//-----------------------------------------//
+// Scoped Lockable Attribute (sl)
+//-----------------------------------------//
+
+#if !__has_attribute(scoped_lockable)
+#error "Should support scoped_lockable attribute"
+#endif
+
+class __attribute__((scoped_lockable)) SLTestClass {
+};
+
+class __attribute__((scoped_lockable (1))) SLTestClass_args { // \
+ // expected-error {{attribute takes no arguments}}
+};
+
+void sl_test_function() __attribute__((scoped_lockable)); // \
+ // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+
+int sl_testfn(int y) {
+ int x __attribute__((scoped_lockable)) = y; // \
+ // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ return x;
+}
+
+int sl_test_var __attribute__((scoped_lockable)); // \
+ // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+
+class SLFoo {
+ private:
+ int test_field __attribute__((scoped_lockable)); // \
+ // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ void test_method() __attribute__((scoped_lockable)); // \
+ // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+};
+
+
+void sl_function_params(int lvar __attribute__((scoped_lockable))); // \
+ // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+
+
+//-----------------------------------------//
+// Guarded By Attribute (gb)
+//-----------------------------------------//
+
+// FIXME: Eventually, would we like this attribute to take more than 1 arg?
+
+#if !__has_attribute(guarded_by)
+#error "Should support guarded_by attribute"
+#endif
+
+//1. Check applied to the right types & argument number
+
+int gb_var_arg __attribute__((guarded_by(mu1)));
+
+int gb_var_args __attribute__((guarded_by(mu1, mu2))); // \
+ // expected-error {{attribute takes one argument}}
+
+int gb_var_noargs __attribute__((guarded_by)); // \
+ // expected-error {{attribute takes one argument}}
+
+class GBFoo {
+ private:
+ int gb_field_noargs __attribute__((guarded_by)); // \
+ // expected-error {{attribute takes one argument}}
+ int gb_field_args __attribute__((guarded_by(mu1)));
+};
+
+class __attribute__((guarded_by(mu1))) GB { // \
+ // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+};
+
+void gb_function() __attribute__((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)))); // \
+ // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+
+int gb_testfn(int y){
+ int x __attribute__((guarded_by(mu1))) = y; // \
+ // expected-warning {{'guarded_by' attribute only applies to fields and global variables}}
+ return x;
+}
+
+//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)));
+
+
+// illegal attribute arguments
+int gb_var_arg_bad_1 __attribute__((guarded_by(1))); // \
+ // expected-error {{'guarded_by' attribute requires arguments that are class type or point to class type}}
+int gb_var_arg_bad_2 __attribute__((guarded_by("mu"))); // \
+ // expected-error {{'guarded_by' attribute requires arguments that are class type or point to class type}}
+int gb_var_arg_bad_3 __attribute__((guarded_by(muDoublePointer))); // \
+ // expected-error {{'guarded_by' attribute requires arguments that are class type or point to class type}}
+int gb_var_arg_bad_4 __attribute__((guarded_by(umu))); // \
+ // expected-error {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+//3.
+// Thread Safety analysis tests
+
+
+//-----------------------------------------//
+// Pt Guarded By Attribute (pgb)
+//-----------------------------------------//
+
+#if !__has_attribute(pt_guarded_by)
+#error "Should support pt_guarded_by attribute"
+#endif
+
+//1. Check applied to the right types & argument number
+
+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_args __attribute__((guarded_by(mu1, mu2))); // \
+ // expected-error {{attribute takes one argument}}
+
+int pgb_var_args __attribute__((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)));
+};
+
+class __attribute__((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))); // \
+ // 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)))); // \
+ // 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); // \
+ // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+ delete x;
+}
+
+//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)));
+
+
+// illegal attribute arguments
+int * pgb_var_arg_bad_1 __attribute__((pt_guarded_by(1))); // \
+ // expected-error {{'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"))); // \
+ // expected-error {{'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-error {{'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))); // \
+ // expected-error {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+
+//-----------------------------------------//
+// Acquired After (aa)
+//-----------------------------------------//
+
+// FIXME: Would we like this attribute to take more than 1 arg?
+
+#if !__has_attribute(acquired_after)
+#error "Should support acquired_after attribute"
+#endif
+
+Mu mu_aa __attribute__((acquired_after(mu1)));
+
+Mu aa_var_noargs __attribute__((acquired_after)); // \
+ // expected-error {{attribute takes at least 1 argument}}
+
+class AAFoo {
+ private:
+ Mu aa_field_noargs __attribute__((acquired_after)); // \
+ // expected-error {{attribute takes at least 1 argument}}
+ Mu aa_field_args __attribute__((acquired_after(mu1)));
+};
+
+class __attribute__((acquired_after(mu1))) AA { // \
+ // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
+};
+
+void aa_function() __attribute__((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)))); // \
+ // expected-warning {{'acquired_after' attribute only applies to fields and global variables}}
+
+void aa_testfn(int y){
+ Mu x __attribute__((acquired_after(mu1))) = Mu(); // \
+ // 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)));
+
+
+// illegal attribute arguments
+Mu aa_var_arg_bad_1 __attribute__((acquired_after(1))); // \
+ // expected-error {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+Mu aa_var_arg_bad_2 __attribute__((acquired_after("mu"))); // \
+ // expected-error {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+Mu aa_var_arg_bad_3 __attribute__((acquired_after(muDoublePointer))); // \
+ // expected-error {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+Mu aa_var_arg_bad_4 __attribute__((acquired_after(umu))); // \
+ // expected-error {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+UnlockableMu aa_var_arg_bad_5 __attribute__((acquired_after(mu_aa))); // \
+ // expected-error {{'acquired_after' attribute can only be applied in a context annotated with 'lockable' attribute}}
+
+//-----------------------------------------//
+// Acquired Before (ab)
+//-----------------------------------------//
+
+#if !__has_attribute(acquired_before)
+#error "Should support acquired_before attribute"
+#endif
+
+Mu mu_ab __attribute__((acquired_before(mu1)));
+
+Mu ab_var_noargs __attribute__((acquired_before)); // \
+ // expected-error {{attribute takes at least 1 argument}}
+
+class ABFoo {
+ private:
+ Mu ab_field_noargs __attribute__((acquired_before)); // \
+ // expected-error {{attribute takes at least 1 argument}}
+ Mu ab_field_args __attribute__((acquired_before(mu1)));
+};
+
+class __attribute__((acquired_before(mu1))) AB { // \
+ // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+};
+
+void ab_function() __attribute__((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)))); // \
+ // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+
+void ab_testfn(int y){
+ Mu x __attribute__((acquired_before(mu1))) = Mu(); // \
+ // expected-warning {{'acquired_before' attribute only applies to fields and global variables}}
+}
+
+// Note: illegal int ab_int __attribute__((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)));
+
+
+// illegal attribute arguments
+Mu ab_var_arg_bad_1 __attribute__((acquired_before(1))); // \
+ // expected-error {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+Mu ab_var_arg_bad_2 __attribute__((acquired_before("mu"))); // \
+ // expected-error {{'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-error {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+Mu ab_var_arg_bad_4 __attribute__((acquired_before(umu))); // \
+ // expected-error {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+UnlockableMu ab_var_arg_bad_5 __attribute__((acquired_before(mu_ab))); // \
+ // expected-error {{'acquired_before' attribute can only be applied in a context annotated with 'lockable' attribute}}
+
+
+//-----------------------------------------//
+// Exclusive Lock Function (elf)
+//-----------------------------------------//
+
+#if !__has_attribute(exclusive_lock_function)
+#error "Should support exclusive_lock_function attribute"
+#endif
+
+// takes zero or more arguments, all locks (vars/fields)
+
+void elf_function() __attribute__((exclusive_lock_function));
+
+void elf_function_args() __attribute__((exclusive_lock_function(mu1, mu2)));
+
+int elf_testfn(int y) __attribute__((exclusive_lock_function));
+
+int elf_testfn(int y) {
+ int x __attribute__((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)); // \
+ // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+
+class ElfFoo {
+ private:
+ int test_field __attribute__((exclusive_lock_function)); // \
+ // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+ void test_method() __attribute__((exclusive_lock_function));
+};
+
+class __attribute__((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))); // \
+ // 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)));
+
+
+// illegal attribute arguments
+int elf_function_bad_2() __attribute__((exclusive_lock_function("mu"))); // \
+ // expected-error {{'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))); // \
+ // expected-error {{'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))); // \
+ // expected-error {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+int elf_function_bad_1() __attribute__((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))); // \
+ // 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))); // \
+ // 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))); // \
+ // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
+
+
+//-----------------------------------------//
+// Shared Lock Function (slf)
+//-----------------------------------------//
+
+#if !__has_attribute(shared_lock_function)
+#error "Should support shared_lock_function attribute"
+#endif
+
+// takes zero or more arguments, all locks (vars/fields)
+
+void slf_function() __attribute__((shared_lock_function));
+
+void slf_function_args() __attribute__((shared_lock_function(mu1, mu2)));
+
+int slf_testfn(int y) __attribute__((shared_lock_function));
+
+int slf_testfn(int y) {
+ int x __attribute__((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)); // \
+ // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+
+void slf_fun_params(int lvar __attribute__((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)); // \
+ // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+ void test_method() __attribute__((shared_lock_function));
+};
+
+class __attribute__((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)));
+
+
+// illegal attribute arguments
+int slf_function_bad_2() __attribute__((shared_lock_function("mu"))); // \
+ // expected-error {{'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-error {{'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))); // \
+ // expected-error {{'shared_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+int slf_function_bad_1() __attribute__((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))); // \
+ // 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))); // \
+ // 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))); // \
+ // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
+
+
+//-----------------------------------------//
+// Exclusive TryLock Function (etf)
+//-----------------------------------------//
+
+#if !__has_attribute(exclusive_trylock_function)
+#error "Should support exclusive_trylock_function attribute"
+#endif
+
+// takes a mandatory boolean or integer argument specifying the retval
+// plus an optional list of locks (vars/fields)
+
+void etf_function() __attribute__((exclusive_trylock_function)); // \
+ // expected-error {{attribute takes attribute takes at least 1 argument arguments}}
+
+void etf_function_args() __attribute__((exclusive_trylock_function(1, mu2)));
+
+void etf_function_arg() __attribute__((exclusive_trylock_function(1)));
+
+int etf_testfn(int y) __attribute__((exclusive_trylock_function(1)));
+
+int etf_testfn(int y) {
+ int x __attribute__((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))); // \
+ // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+
+class EtfFoo {
+ private:
+ int test_field __attribute__((exclusive_trylock_function(1))); // \
+ // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+ void test_method() __attribute__((exclusive_trylock_function(1)));
+};
+
+class __attribute__((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)))); // \
+ // 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)));
+
+
+// illegal attribute arguments
+int etf_function_bad_1() __attribute__((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"))); // \
+ // 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))); // \
+ // 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-error {{'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))); // \
+ // expected-error {{'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))); // \
+ // expected-error {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+
+//-----------------------------------------//
+// Shared TryLock Function (stf)
+//-----------------------------------------//
+
+#if !__has_attribute(shared_trylock_function)
+#error "Should support shared_trylock_function attribute"
+#endif
+
+// takes a mandatory boolean or integer argument specifying the retval
+// plus an optional list of locks (vars/fields)
+
+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_arg() __attribute__((shared_trylock_function(1)));
+
+int stf_testfn(int y) __attribute__((shared_trylock_function(1)));
+
+int stf_testfn(int y) {
+ int x __attribute__((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))); // \
+ // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+
+void stf_fun_params(int lvar __attribute__((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))); // \
+ // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+ void test_method() __attribute__((shared_trylock_function(1)));
+};
+
+class __attribute__((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)));
+
+
+// illegal attribute arguments
+int stf_function_bad_1() __attribute__((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"))); // \
+ // 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))); // \
+ // 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"))); // \
+ // expected-error {{'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-error {{'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))); // \
+ // expected-error {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+
+//-----------------------------------------//
+// Unlock Function (uf)
+//-----------------------------------------//
+
+#if !__has_attribute(unlock_function)
+#error "Should support unlock_function attribute"
+#endif
+
+// takes zero or more arguments, all locks (vars/fields)
+
+void uf_function() __attribute__((unlock_function));
+
+void uf_function_args() __attribute__((unlock_function(mu1, mu2)));
+
+int uf_testfn(int y) __attribute__((unlock_function));
+
+int uf_testfn(int y) {
+ int x __attribute__((unlock_function)) = y; // \
+ // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+ return x;
+};
+
+int uf_test_var __attribute__((unlock_function)); // \
+ // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+
+class UfFoo {
+ private:
+ int test_field __attribute__((unlock_function)); // \
+ // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+ void test_method() __attribute__((unlock_function));
+};
+
+class __attribute__((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))); // \
+ // 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)));
+
+
+// illegal attribute arguments
+int uf_function_bad_2() __attribute__((unlock_function("mu"))); // \
+ // expected-error {{'unlock_function' attribute requires arguments that are class type or point to class type}}
+int uf_function_bad_3() __attribute__((unlock_function(muDoublePointer))); // \
+ // expected-error {{'unlock_function' attribute requires arguments that are class type or point to class type}}
+int uf_function_bad_4() __attribute__((unlock_function(umu))); // \
+ // expected-error {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+int uf_function_bad_1() __attribute__((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))); // \
+ // 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))); // \
+ // 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))); // \
+ // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
+
+
+//-----------------------------------------//
+// Lock Returned (lr)
+//-----------------------------------------//
+
+#if !__has_attribute(lock_returned)
+#error "Should support lock_returned attribute"
+#endif
+
+// Takes exactly one argument, a var/field
+
+void lr_function() __attribute__((lock_returned)); // \
+ // expected-error {{attribute takes one argument}}
+
+void lr_function_arg() __attribute__((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) {
+ int x __attribute__((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))); // \
+ // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+
+void lr_fun_params(int lvar __attribute__((lock_returned(mu1)))); // \
+ // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+
+class LrFoo {
+ private:
+ int test_field __attribute__((lock_returned(mu1))); // \
+ // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+ void test_method() __attribute__((lock_returned(mu1)));
+};
+
+class __attribute__((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)));
+
+
+// illegal attribute arguments
+int lr_function_bad_1() __attribute__((lock_returned(1))); // \
+ // expected-error {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+int lr_function_bad_2() __attribute__((lock_returned("mu"))); // \
+ // expected-error {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+int lr_function_bad_3() __attribute__((lock_returned(muDoublePointer))); // \
+ // expected-error {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+int lr_function_bad_4() __attribute__((lock_returned(umu))); // \
+ // expected-error {{'lock_returned' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+
+
+//-----------------------------------------//
+// Locks Excluded (le)
+//-----------------------------------------//
+
+#if !__has_attribute(locks_excluded)
+#error "Should support locks_excluded attribute"
+#endif
+
+// takes one or more arguments, all locks (vars/fields)
+
+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_args() __attribute__((locks_excluded(mu1, mu2)));
+
+int le_testfn(int y) __attribute__((locks_excluded(mu1)));
+
+int le_testfn(int y) {
+ int x __attribute__((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))); // \
+ // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+
+void le_fun_params(int lvar __attribute__((locks_excluded(mu1)))); // \
+ // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+
+class LeFoo {
+ private:
+ int test_field __attribute__((locks_excluded(mu1))); // \
+ // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+ void test_method() __attribute__((locks_excluded(mu1)));
+};
+
+class __attribute__((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)));
+
+
+// illegal attribute arguments
+int le_function_bad_1() __attribute__((locks_excluded(1))); // \
+ // expected-error {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+int le_function_bad_2() __attribute__((locks_excluded("mu"))); // \
+ // expected-error {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+int le_function_bad_3() __attribute__((locks_excluded(muDoublePointer))); // \
+ // expected-error {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+int le_function_bad_4() __attribute__((locks_excluded(umu))); // \
+ // expected-error {{'locks_excluded' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+
+
+//-----------------------------------------//
+// Exclusive Locks Required (elr)
+//-----------------------------------------//
+
+#if !__has_attribute(exclusive_locks_required)
+#error "Should support exclusive_locks_required attribute"
+#endif
+
+// takes one or more arguments, all locks (vars/fields)
+
+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_args() __attribute__((exclusive_locks_required(mu1, mu2)));
+
+int elr_testfn(int y) __attribute__((exclusive_locks_required(mu1)));
+
+int elr_testfn(int y) {
+ int x __attribute__((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))); // \
+ // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+
+void elr_fun_params(int lvar __attribute__((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))); // \
+ // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+ void test_method() __attribute__((exclusive_locks_required(mu1)));
+};
+
+class __attribute__((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)));
+
+
+// illegal attribute arguments
+int elr_function_bad_1() __attribute__((exclusive_locks_required(1))); // \
+ // expected-error {{'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"))); // \
+ // expected-error {{'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-error {{'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))); // \
+ // expected-error {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+
+
+
+//-----------------------------------------//
+// Shared Locks Required (slr)
+//-----------------------------------------//
+
+#if !__has_attribute(shared_locks_required)
+#error "Should support shared_locks_required attribute"
+#endif
+
+// takes one or more arguments, all locks (vars/fields)
+
+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_args() __attribute__((shared_locks_required(mu1, mu2)));
+
+int slr_testfn(int y) __attribute__((shared_locks_required(mu1)));
+
+int slr_testfn(int y) {
+ int x __attribute__((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))); // \
+ // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+
+void slr_fun_params(int lvar __attribute__((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))); // \
+ // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+ void test_method() __attribute__((shared_locks_required(mu1)));
+};
+
+class __attribute__((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)));
+
+
+// illegal attribute arguments
+int slr_function_bad_1() __attribute__((shared_locks_required(1))); // \
+ // expected-error {{'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"))); // \
+ // expected-error {{'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))); // \
+ // expected-error {{'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))); // \
+ // expected-error {{'shared_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+
+
+//-----------------------------------------//
+// Regression tests for unusual cases.
+//-----------------------------------------//
+
+int trivially_false_edges(bool b) {
+ // Create NULL (never taken) edges in CFG
+ if (false) return 1;
+ else return 2;
+}
+
+// Possible Clang bug -- method pointer in template parameter
+class UnFoo {
+public:
+ void foo();
+};
+
+template<void (UnFoo::*methptr)()>
+class MCaller {
+public:
+ static void call_method_ptr(UnFoo *f) {
+ // FIXME: Possible Clang bug:
+ // getCalleeDecl() returns NULL in the following case:
+ (f->*methptr)();
+ }
+};
+
+void call_method_ptr_inst(UnFoo* f) {
+ MCaller<&UnFoo::foo>::call_method_ptr(f);
+}
+
+int temp;
+void empty_back_edge() {
+ // Create a back edge to a block with with no statements
+ for (;;) {
+ ++temp;
+ if (temp > 10) break;
+ }
+}
+
+struct Foomger {
+ void operator++();
+};
+
+struct Foomgoper {
+ Foomger f;
+
+ bool done();
+ void invalid_back_edge() {
+ do {
+ // FIXME: Possible Clang bug:
+ // The first statement in this basic block has no source location
+ ++f;
+ } while (!done());
+ }
+};
+
+
+//-----------------------------------------------------
+// Parsing of member variables and function parameters
+//------------------------------------------------------
+
+Mu gmu;
+
+class StaticMu {
+ static Mu 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)));
+
+ static void foo5() __attribute__((exclusive_locks_required(mu))); // \
+ // expected-error {{invalid use of member 'mu' in static member function}}
+
+ template <class T>
+ void foo6() __attribute__((exclusive_locks_required(T::statmu))) { }
+
+ template <class T>
+ void foo7(T* f) __attribute__((exclusive_locks_required(f->mu))) { }
+
+ int a __attribute__((guarded_by(gmu)));
+ int b __attribute__((guarded_by(mu)));
+ int c __attribute__((guarded_by(this->mu)));
+
+ Mu mu;
+};
+
diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp
index ea6755f2d6ce..604a3c0da381 100644
--- a/test/SemaCXX/warn-unreachable.cpp
+++ b/test/SemaCXX/warn-unreachable.cpp
@@ -45,8 +45,8 @@ void test3() {
?
dead() : dead();
live(),
- float // expected-warning {{will never be executed}}
- (halt());
+ float
+ (halt()); // expected-warning {{will never be executed}}
}
void test4() {
@@ -73,6 +73,6 @@ void test6() {
S(int i) { }
};
live(),
- S // expected-warning {{will never be executed}}
- (halt());
+ S
+ (halt()); // expected-warning {{will never be executed}}
}
diff --git a/test/SemaCXX/warn-unused-comparison.cpp b/test/SemaCXX/warn-unused-comparison.cpp
new file mode 100644
index 000000000000..0153f213ba1f
--- /dev/null
+++ b/test/SemaCXX/warn-unused-comparison.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -Wno-unused -Wunused-comparison %s
+
+struct A {
+ bool operator==(const A&);
+ bool operator!=(const A&);
+ A operator|=(const A&);
+ operator bool();
+};
+
+void test() {
+ int x, *p;
+ A a, b;
+
+ x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ x != 7; // expected-warning {{inequality comparison result unused}} \
+ // expected-note {{use '|=' to turn this inequality comparison into an or-assignment}}
+ 7 == x; // expected-warning {{equality comparison result unused}}
+ p == p; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}} \
+ // expected-warning {{self-comparison always evaluates to true}}
+ a == a; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ a == b; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ a != b; // expected-warning {{inequality comparison result unused}} \
+ // expected-note {{use '|=' to turn this inequality comparison into an or-assignment}}
+ A() == b; // expected-warning {{equality comparison result unused}}
+ if (42) x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ else if (42) x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ else x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ do x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ while (false);
+ while (false) x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ for (x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ x == 7; // No warning -- result is used
+ x == 7) // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ switch (42) default: x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ switch (42) case 42: x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ switch (42) {
+ case 1:
+ case 2:
+ default:
+ case 3:
+ case 4:
+ x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ }
+
+ (void)(x == 7);
+ (void)(p == p); // expected-warning {{self-comparison always evaluates to true}}
+ { bool b = x == 7; }
+
+ { bool b = ({ x == 7; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ x == 7; }); } // no warning on the second, its result is used!
+
+#define EQ(x,y) (x) == (y)
+ EQ(x, 5);
+#undef EQ
+}
+
+namespace PR10291 {
+ template<typename T>
+ class X
+ {
+ public:
+
+ X() : i(0) { }
+
+ void foo()
+ {
+ throw
+ i == 0u ?
+ 5 : 6;
+ }
+
+ private:
+ int i;
+ };
+
+ X<int> x;
+}
diff --git a/test/SemaCXX/warn-unused-value.cpp b/test/SemaCXX/warn-unused-value.cpp
index 775c3cf01f24..80298ec6664a 100644
--- a/test/SemaCXX/warn-unused-value.cpp
+++ b/test/SemaCXX/warn-unused-value.cpp
@@ -15,3 +15,18 @@ namespace test0 {
box->j;
}
}
+
+namespace test1 {
+struct Foo {
+ int i;
+ bool operator==(const Foo& rhs) {
+ return i == rhs.i;
+ }
+};
+
+#define NOP(x) (x)
+void b(Foo f1, Foo f2) {
+ NOP(f1 == f2); // expected-warning {{expression result unused}}
+}
+#undef NOP
+}
diff --git a/test/SemaCXX/warn-weak-vtables.cpp b/test/SemaCXX/warn-weak-vtables.cpp
index c0cfd74a3e52..912622f5a7e4 100644
--- a/test/SemaCXX/warn-weak-vtables.cpp
+++ b/test/SemaCXX/warn-weak-vtables.cpp
@@ -29,3 +29,30 @@ void uses(A &a, B<int> &b, C &c) {
b.f();
c.f();
}
+
+// <rdar://problem/9979458>
+class Parent {
+public:
+ Parent() {}
+ virtual ~Parent();
+ virtual void * getFoo() const = 0;
+};
+
+class Derived : public Parent {
+public:
+ Derived();
+ void * getFoo() const;
+};
+
+class VeryDerived : public Derived { // expected-warning{{'VeryDerived' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
+public:
+ void * getFoo() const { return 0; }
+};
+
+Parent::~Parent() {}
+
+void uses(Parent &p, Derived &d, VeryDerived &vd) {
+ p.getFoo();
+ d.getFoo();
+ vd.getFoo();
+}