Updated to Clang 3.5a.
Change-Id: I8127eb568f674c2e72635b639a3295381fe8af82
diff --git a/test/SemaCXX/MicrosoftCompatibility.cpp b/test/SemaCXX/MicrosoftCompatibility.cpp
index 05037ac..fb7d975 100644
--- a/test/SemaCXX/MicrosoftCompatibility.cpp
+++ b/test/SemaCXX/MicrosoftCompatibility.cpp
@@ -3,6 +3,7 @@
typedef unsigned short char16_t;
typedef unsigned int char32_t;
+struct _Atomic {};
typename decltype(3) a; // expected-warning {{expected a qualified name after 'typename'}}
@@ -21,6 +22,12 @@
}
+namespace ms_predefined_types {
+ // ::type_info is a built-in forward class declaration.
+ void f(const type_info &a);
+ void f(size_t);
+}
+
namespace ms_protected_scope {
struct C { C(); };
@@ -105,6 +112,9 @@
class B : public A {
private:
using A::f;
+ void g() {
+ f(); // no diagnostic
+ }
};
class C : public B {
@@ -114,6 +124,27 @@
}
+namespace using_tag_redeclaration
+{
+ struct S;
+ namespace N {
+ using ::using_tag_redeclaration::S;
+ struct S {}; // expected-note {{previous definition is here}}
+ }
+ void f() {
+ N::S s1;
+ S s2;
+ }
+ void g() {
+ struct S; // expected-note {{forward declaration of 'S'}}
+ S s3; // expected-error {{variable has incomplete type 'S'}}
+ }
+ void h() {
+ using ::using_tag_redeclaration::S;
+ struct S {}; // expected-error {{redefinition of 'S'}}
+ }
+}
+
namespace MissingTypename {
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index c5b45a2..0f6ebbb 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -1,10 +1,6 @@
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions
-// ::type_info is predeclared with forward class declartion
-void f(const type_info &a);
-
-
// Microsoft doesn't validate exception specification.
namespace microsoft_exception_spec {
@@ -37,11 +33,11 @@
// MSVC allows type definition in anonymous union and struct
struct A
{
- union
+ union
{
int a;
struct B // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
- {
+ {
int c;
} d;
@@ -63,7 +59,7 @@
{
int c2;
} d2;
-
+
union C2 // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
{
int e2;
@@ -78,7 +74,7 @@
// __stdcall handling
struct M {
int __stdcall addP();
- float __stdcall subtractP();
+ float __stdcall subtractP();
};
// __unaligned handling
@@ -90,7 +86,7 @@
void m1() {
h1<int>(&M::addP);
h1(&M::subtractP);
-}
+}
@@ -98,7 +94,7 @@
void f(long long);
void f(int);
-
+
int main()
{
// This is an ambiguous call in standard C++.
@@ -123,10 +119,11 @@
class AAA {
__declspec(dllimport) void f(void) { }
-void f2(void);
+void f2(void); // expected-note{{previous declaration is here}}
};
-__declspec(dllimport) void AAA::f2(void) { // expected-error {{dllimport attribute can be applied only to symbol}}
+__declspec(dllimport) void AAA::f2(void) { // expected-error{{'dllimport' attribute can be applied only to symbol}}
+ // expected-error@-1{{redeclaration of 'AAA::f2' cannot add 'dllimport' attribute}}
}
@@ -307,7 +304,7 @@
__declspec(property(get=GetV, put=SetV)) T V;
T GetV() { return 0; }
void SetV(T v) {}
- void f() { V = this->V; V < this->V; }
+ bool f() { V = this->V; return V < this->V; }
void g() { V++; }
void h() { V*=2; }
};
@@ -368,18 +365,18 @@
namespace rdar14250378 {
class Bar {};
-
+
namespace NyNamespace {
class Foo {
public:
Bar* EnsureBar();
};
-
+
class Baz : public Foo {
public:
friend class Bar;
};
-
+
Bar* Foo::EnsureBar() {
return 0;
}
@@ -410,3 +407,14 @@
// expected-error@+1 {{base 'SealedType' is marked 'sealed'}}
struct InheritFromSealed : SealedType {};
+
+void AfterClassBody() {
+ // expected-warning@+1 {{attribute 'deprecated' is ignored, place it after "struct" to apply attribute to type declaration}}
+ struct D {} __declspec(deprecated);
+
+ struct __declspec(align(4)) S {} __declspec(align(8)) s1;
+ S s2;
+ _Static_assert(__alignof(S) == 4, "");
+ _Static_assert(__alignof(s1) == 8, "");
+ _Static_assert(__alignof(s2) == 4, "");
+}
diff --git a/test/SemaCXX/PR8012.cpp b/test/SemaCXX/PR8012.cpp
index 9cfc2b0..0a43af7 100644
--- a/test/SemaCXX/PR8012.cpp
+++ b/test/SemaCXX/PR8012.cpp
@@ -1,3 +1,3 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
-void foo (int operator+); // expected-error{{cannot be the name of a parameter}}
+void foo(int operator+); // expected-error{{'operator+' cannot be the name of a parameter}}
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
index d7e2d0a..b521196 100644
--- a/test/SemaCXX/abstract.cpp
+++ b/test/SemaCXX/abstract.cpp
@@ -268,16 +268,16 @@
}
namespace pr12658 {
- class C {
- public:
- C(int v){}
- virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
- };
-
- void foo( C& c ) {}
-
- void bar( void ) {
- foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
+ class C {
+ public:
+ C(int v){}
+ virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
+ };
+
+ void foo( C& c ) {}
+
+ void bar( void ) {
+ foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
}
}
diff --git a/test/SemaCXX/access.cpp b/test/SemaCXX/access.cpp
index 5ccd418..5fa1509 100644
--- a/test/SemaCXX/access.cpp
+++ b/test/SemaCXX/access.cpp
@@ -136,3 +136,25 @@
};
}
}
+
+namespace LocalExternVar {
+ class test {
+ private:
+ struct private_struct { // expected-note 2{{here}}
+ int x;
+ };
+ int use_private();
+ };
+
+ int test::use_private() {
+ extern int array[sizeof(test::private_struct)]; // ok
+ return array[0];
+ }
+
+ int f() {
+ extern int array[sizeof(test::private_struct)]; // expected-error {{private}}
+ return array[0];
+ }
+
+ int array[sizeof(test::private_struct)]; // expected-error {{private}}
+}
diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp
index 230a1eb..358fe8d 100644
--- a/test/SemaCXX/addr-of-overloaded-function.cpp
+++ b/test/SemaCXX/addr-of-overloaded-function.cpp
@@ -84,7 +84,7 @@
void h() {
// Do not suggest '()' since an int argument is required
- q1<int>; // expected-error-re{{reference to non-static member function must be called$}}
+ q1<int>; // expected-error-re{{reference to non-static member function must be called{{$}}}}
// Suggest '()' since there's a default value for the only argument & the
// type argument is already provided
q2<int>; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
@@ -92,7 +92,7 @@
// already provided
q3<int>; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
// Do not suggest '()' since another type argument is required
- q4<int>; // expected-error-re{{reference to non-static member function must be called$}}
+ q4<int>; // expected-error-re{{reference to non-static member function must be called{{$}}}}
// Suggest '()' since the type parameter has a default value
q5; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
}
@@ -220,20 +220,20 @@
void QualifierTest() {
void (Qualifiers::*X)();
- X = &Qualifiers::C; // expected-error {{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const': different qualifiers (none vs const)}}
- X = &Qualifiers::V; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() volatile': different qualifiers (none vs volatile)}}
- X = &Qualifiers::R; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() restrict': different qualifiers (none vs restrict)}}
- X = &Qualifiers::CV; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const volatile': different qualifiers (none vs const and volatile)}}
- X = &Qualifiers::CR; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const restrict': different qualifiers (none vs const and restrict)}}
- X = &Qualifiers::VR; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() volatile restrict': different qualifiers (none vs volatile and restrict)}}
- X = &Qualifiers::CVR; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const volatile restrict': different qualifiers (none vs const, volatile, and restrict)}}
+ X = &Qualifiers::C; // expected-error-re {{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (none vs const)}}
+ X = &Qualifiers::V; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (none vs volatile)}}
+ X = &Qualifiers::R; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} restrict': different qualifiers (none vs restrict)}}
+ X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (none vs const and volatile)}}
+ X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const restrict': different qualifiers (none vs const and restrict)}}
+ X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile restrict': different qualifiers (none vs volatile and restrict)}}
+ X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile restrict': different qualifiers (none vs const, volatile, and restrict)}}
}
struct Dummy {
void N() {};
};
- void (Qualifiers::*X)() = &Dummy::N; // expected-error{{cannot initialize a variable of type 'void (test1::Qualifiers::*)()' with an rvalue of type 'void (test1::Dummy::*)()': different classes ('test1::Qualifiers' vs 'test1::Dummy')}}
+ void (Qualifiers::*X)() = &Dummy::N; // expected-error-re{{cannot initialize a variable of type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (test1::Dummy::*)(){{( __attribute__\(\(thiscall\)\))?}}': different classes ('test1::Qualifiers' vs 'test1::Dummy')}}
}
template <typename T> class PR16561 {
diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp
index 885bf70..4e41774 100644
--- a/test/SemaCXX/aggregate-initialization.cpp
+++ b/test/SemaCXX/aggregate-initialization.cpp
@@ -49,7 +49,7 @@
A(int);
~A();
- A(const A&) = delete; // expected-note 2 {{function has been explicitly marked deleted here}}
+ A(const A&) = delete; // expected-note 2 {{'A' has been explicitly marked deleted here}}
};
struct B {
diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp
index db9c82a..89efc50 100644
--- a/test/SemaCXX/alias-template.cpp
+++ b/test/SemaCXX/alias-template.cpp
@@ -102,10 +102,10 @@
};
namespace TagName {
- template<typename Z> using S = struct { int n; }; // expected-error {{can not be defined}}
- template<typename Z> using T = class { int n; }; // expected-error {{can not be defined}}
- template<typename Z> using U = enum { a, b, c }; // expected-error {{can not be defined}}
- template<typename Z> using V = struct V { int n; }; // expected-error {{'TagName::V' can not be defined in a type alias template}}
+ template<typename Z> using S = struct { int n; }; // expected-error {{cannot be defined}}
+ template<typename Z> using T = class { int n; }; // expected-error {{cannot be defined}}
+ template<typename Z> using U = enum { a, b, c }; // expected-error {{cannot be defined}}
+ template<typename Z> using V = struct V { int n; }; // expected-error {{'TagName::V' cannot be defined in a type alias template}}
}
namespace StdExample {
@@ -136,7 +136,7 @@
namespace VoidArg {
template<typename Z> using V = void;
V<int> f(int); // ok
- V<char> g(V<double>); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}}
+ V<char> g(V<double>); // ok (DR577)
}
namespace Curried {
diff --git a/test/SemaCXX/anonymous-struct.cpp b/test/SemaCXX/anonymous-struct.cpp
index 8a61041..1b5dc13 100644
--- a/test/SemaCXX/anonymous-struct.cpp
+++ b/test/SemaCXX/anonymous-struct.cpp
@@ -14,3 +14,10 @@
static struct {
};
};
+
+template <class T> void foo(T);
+typedef struct { // expected-note {{use a tag name here to establish linkage prior to definition}} expected-note {{declared here}}
+ void test() {
+ foo(this); // expected-warning {{template argument uses unnamed type}}
+ }
+} A; // expected-error {{unsupported: typedef changes linkage of anonymous type, but linkage was already computed}}
diff --git a/test/SemaCXX/ast-print.cpp b/test/SemaCXX/ast-print.cpp
index a1975b4..3d98fd8 100644
--- a/test/SemaCXX/ast-print.cpp
+++ b/test/SemaCXX/ast-print.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -ast-print %s -std=gnu++11 | FileCheck %s
// CHECK: r;
// CHECK-NEXT: (r->method());
@@ -164,3 +164,35 @@
void test14() {
struct X { union { int x; } x; };
}
+
+
+// CHECK: float test15() {
+// CHECK: return __builtin_asinf(1.F);
+// CHECK: }
+// CHECK-NOT: extern "C"
+float test15() {
+ return __builtin_asinf(1.0F);
+}
+
+namespace PR18776 {
+struct A {
+ operator void *();
+ explicit operator bool();
+ A operator&(A);
+};
+
+// CHECK: struct A
+// CHECK-NEXT: {{^[ ]*operator}} void *();
+// CHECK-NEXT: {{^[ ]*explicit}} operator bool();
+
+void bar(void *);
+
+void foo() {
+ A a, b;
+ bar(a & b);
+// CHECK: bar(a & b);
+ if (a & b)
+// CHECK: if (a & b)
+ return;
+}
+};
diff --git a/test/SemaCXX/attr-common.cpp b/test/SemaCXX/attr-common.cpp
index 58b3013..fb98639 100644
--- a/test/SemaCXX/attr-common.cpp
+++ b/test/SemaCXX/attr-common.cpp
@@ -1,3 +1,3 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-__attribute__((common)) int x; // expected-error {{common attribute is not supported in C++}}
+__attribute__((common)) int x; // expected-error {{'common' attribute is not supported in C++}}
diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp
index e24e12e..6ba89a6 100644
--- a/test/SemaCXX/attr-cxx0x.cpp
+++ b/test/SemaCXX/attr-cxx0x.cpp
@@ -45,3 +45,8 @@
static_assert(alignof(outer<int,char>::inner<double,short>) == alignof(int) * alignof(double), "template's alignment is wrong");
static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-error{{invalid application of 'alignof' to a function type}}
+
+[[__carries_dependency__]] // expected-warning{{unknown attribute '__carries_dependency__' ignored}}
+void func(void);
+
+alignas(4) auto PR19252 = 0;
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index b3223f3..d28eb75 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 %s -verify -fexceptions
class A {
- void f() __attribute__((deprecated)); // expected-note 2 {{declared here}}
+ void f() __attribute__((deprecated)); // expected-note 2 {{'f' has been explicitly marked deprecated here}}
void g(A* a);
void h(A* a) __attribute__((deprecated));
- int b __attribute__((deprecated)); // expected-note 2 {{declared here}}
+ int b __attribute__((deprecated)); // expected-note 2 {{'b' has been explicitly marked deprecated here}}
};
void A::g(A* a)
@@ -26,7 +26,7 @@
}
struct B {
- virtual void f() __attribute__((deprecated)); // expected-note 4 {{declared here}}
+ virtual void f() __attribute__((deprecated)); // expected-note 4 {{'f' has been explicitly marked deprecated here}}
void g();
};
@@ -68,20 +68,20 @@
// Overloaded namespace members.
namespace test1 {
- void foo(int) __attribute__((deprecated)); // expected-note {{declared here}}
+ void foo(int) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
void test1() { foo(10); } // expected-warning {{deprecated}}
- void foo(short) __attribute__((deprecated)); // expected-note {{declared here}}
+ void foo(short) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
void test2(short s) { foo(s); } // expected-warning {{deprecated}}
void foo(long);
void test3(long l) { foo(l); }
struct A {
- friend void foo(A*) __attribute__((deprecated)); // expected-note {{declared here}}
+ friend void foo(A*) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
};
void test4(A *a) { foo(a); } // expected-warning {{deprecated}}
namespace ns {
struct Foo {};
- void foo(const Foo &f) __attribute__((deprecated)); // expected-note {{declared here}}
+ void foo(const Foo &f) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
}
void test5() {
foo(ns::Foo()); // expected-warning {{deprecated}}
@@ -91,9 +91,9 @@
// Overloaded class members.
namespace test2 {
struct A {
- void foo(int) __attribute__((deprecated)); // expected-note 2 {{declared here}}
+ void foo(int) __attribute__((deprecated)); // expected-note 2 {{'foo' has been explicitly marked deprecated here}}
void foo(long);
- static void bar(int) __attribute__((deprecated)); // expected-note 3 {{declared here}}
+ static void bar(int) __attribute__((deprecated)); // expected-note 3 {{'bar' has been explicitly marked deprecated here}}
static void bar(long);
void test2(int i, long l);
@@ -120,12 +120,12 @@
namespace test3 {
struct A {
void operator*(const A &);
- void operator*(int) __attribute__((deprecated)); // expected-note {{declared here}}
+ void operator*(int) __attribute__((deprecated)); // expected-note {{'operator*' has been explicitly marked deprecated here}}
void operator-(const A &) const;
};
void operator+(const A &, const A &);
- void operator+(const A &, int) __attribute__((deprecated)); // expected-note {{declared here}}
- void operator-(const A &, int) __attribute__((deprecated)); // expected-note {{declared here}}
+ void operator+(const A &, int) __attribute__((deprecated)); // expected-note {{'operator+' has been explicitly marked deprecated here}}
+ void operator-(const A &, int) __attribute__((deprecated)); // expected-note {{'operator-' has been explicitly marked deprecated here}}
void test() {
A a, b;
@@ -143,9 +143,9 @@
struct A {
typedef void (*intfn)(int);
typedef void (*unintfn)(unsigned);
- operator intfn() __attribute__((deprecated)); // expected-note {{declared here}}
+ operator intfn() __attribute__((deprecated)); // expected-note {{'operator void (*)(int)' has been explicitly marked deprecated here}}
operator unintfn();
- void operator ()(A &) __attribute__((deprecated)); // expected-note {{declared here}}
+ void operator ()(A &) __attribute__((deprecated)); // expected-note {{'operator()' has been explicitly marked deprecated here}}
void operator ()(const A &);
};
@@ -163,7 +163,7 @@
namespace test5 {
struct A {
- operator int() __attribute__((deprecated)); // expected-note 3 {{declared here}}
+ operator int() __attribute__((deprecated)); // expected-note 3 {{'operator int' has been explicitly marked deprecated here}}
operator long();
};
void test1(A a) {
@@ -193,8 +193,8 @@
// rdar://problem/8518751
namespace test6 {
- enum __attribute__((deprecated)) A { // expected-note {{declared here}}
- a0 // expected-note {{declared here}}
+ enum __attribute__((deprecated)) A { // expected-note {{'A' has been explicitly marked deprecated here}}
+ a0 // expected-note {{'a0' has been explicitly marked deprecated here}}
};
void testA() {
A x; // expected-warning {{'A' is deprecated}}
@@ -202,7 +202,7 @@
}
enum B {
- b0 __attribute__((deprecated)), // expected-note {{declared here}}
+ b0 __attribute__((deprecated)), // expected-note {{'b0' has been explicitly marked deprecated here}}
b1
};
void testB() {
@@ -212,8 +212,8 @@
}
template <class T> struct C {
- enum __attribute__((deprecated)) Enum { // expected-note {{declared here}}
- c0 // expected-note {{declared here}}
+ enum __attribute__((deprecated)) Enum { // expected-note {{'Enum' has been explicitly marked deprecated here}}
+ c0 // expected-note {{'c0' has been explicitly marked deprecated here}}
};
};
void testC() {
@@ -224,7 +224,7 @@
template <class T> struct D {
enum Enum {
d0,
- d1 __attribute__((deprecated)), // expected-note {{declared here}}
+ d1 __attribute__((deprecated)), // expected-note {{'d1' has been explicitly marked deprecated here}}
};
};
void testD() {
@@ -236,8 +236,8 @@
namespace test7 {
struct X {
- void* operator new(typeof(sizeof(void*))) __attribute__((deprecated)); // expected-note{{'operator new' declared here}}
- void operator delete(void *) __attribute__((deprecated)); // expected-note{{'operator delete' declared here}}
+ void* operator new(typeof(sizeof(void*))) __attribute__((deprecated)); // expected-note{{'operator new' has been explicitly marked deprecated here}}
+ void operator delete(void *) __attribute__((deprecated)); // expected-note{{'operator delete' has been explicitly marked deprecated here}}
};
void test() {
@@ -247,6 +247,6 @@
// rdar://problem/15044218
typedef struct TDS {
-} TDS __attribute__((deprecated)); // expected-note {{'TDS' declared here}}
+} TDS __attribute__((deprecated)); // expected-note {{'TDS' has been explicitly marked deprecated here}}
TDS tds; // expected-warning {{'TDS' is deprecated}}
struct TDS tds2; // no warning, attribute only applies to the typedef.
diff --git a/test/SemaCXX/attr-optnone.cpp b/test/SemaCXX/attr-optnone.cpp
new file mode 100644
index 0000000..eaa5000
--- /dev/null
+++ b/test/SemaCXX/attr-optnone.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -verify %s
+
+int foo() __attribute__((optnone));
+int bar() __attribute__((optnone)) __attribute__((noinline));
+
+int baz() __attribute__((always_inline)) __attribute__((optnone)); // expected-error{{'always_inline' and 'optnone' attributes are not compatible}}
+int quz() __attribute__((optnone)) __attribute__((always_inline)); // expected-error{{'optnone' and 'always_inline' attributes are not compatible}}
+
+__forceinline __attribute__((optnone)) int bax(); // expected-error{{'__forceinline' and 'optnone' attributes are not compatible}}
+__attribute__((optnone)) __forceinline int qux(); // expected-error{{'optnone' and '__forceinline' attributes are not compatible}}
+
+int globalVar __attribute__((optnone)); // expected-warning{{'optnone' attribute only applies to functions}}
+
+int fubar(int __attribute__((optnone)), int); // expected-warning{{'optnone' attribute only applies to functions}}
+
+struct A {
+ int aField __attribute__((optnone)); // expected-warning{{'optnone' attribute only applies to functions}}
+};
+
+struct B {
+ void foo() __attribute__((optnone));
+ static void bar() __attribute__((optnone));
+};
+
+// Verify that we can specify the [[clang::optnone]] syntax as well.
+
+[[clang::optnone]]
+int foo2();
+[[clang::optnone]]
+int bar2() __attribute__((noinline));
+
+[[clang::optnone]]
+int baz2() __attribute__((always_inline)); // expected-error{{'always_inline' and 'optnone' attributes are not compatible}}
+
+[[clang::optnone]] int globalVar2; //expected-warning{{'optnone' attribute only applies to functions}}
+
+struct A2 {
+ [[clang::optnone]] int aField; // expected-warning{{'optnone' attribute only applies to functions}}
+};
+
+struct B2 {
+ [[clang::optnone]]
+ void foo();
+ [[clang::optnone]]
+ static void bar();
+};
+
diff --git a/test/SemaCXX/attr-selectany.cpp b/test/SemaCXX/attr-selectany.cpp
index 0f9776d..c27a915 100644
--- a/test/SemaCXX/attr-selectany.cpp
+++ b/test/SemaCXX/attr-selectany.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -std=c++11 %s
// MSVC produces similar diagnostics.
__declspec(selectany) void foo() { } // expected-error{{'selectany' can only be applied to data items with external linkage}}
@@ -31,3 +31,6 @@
};
__declspec(selectany) X x(1);
+
+namespace { class Internal {}; }
+__declspec(selectany) auto x8 = Internal(); // expected-error {{'selectany' can only be applied to data items with external linkage}}
diff --git a/test/SemaCXX/attr-unavailable.cpp b/test/SemaCXX/attr-unavailable.cpp
index 2d82668..51dc8fe 100644
--- a/test/SemaCXX/attr-unavailable.cpp
+++ b/test/SemaCXX/attr-unavailable.cpp
@@ -3,7 +3,7 @@
int &foo(int); // expected-note {{candidate}}
double &foo(double); // expected-note {{candidate}}
void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \
-// expected-note{{function has been explicitly marked unavailable here}}
+// expected-note{{'foo' has been explicitly marked unavailable here}}
void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}}
@@ -37,3 +37,22 @@
foo(sp);
foo();
}
+
+// Show that delayed processing of 'unavailable' is the same
+// delayed process for 'deprecated'.
+// <rdar://problem/12241361> and <rdar://problem/15584219>
+enum DeprecatedEnum { DE_A, DE_B } __attribute__((deprecated)); // expected-note {{'DeprecatedEnum' has been explicitly marked deprecated here}}
+__attribute__((deprecated)) typedef enum DeprecatedEnum DeprecatedEnum;
+typedef enum DeprecatedEnum AnotherDeprecatedEnum; // expected-warning {{'DeprecatedEnum' is deprecated}}
+
+__attribute__((deprecated))
+DeprecatedEnum testDeprecated(DeprecatedEnum X) { return X; }
+
+
+enum UnavailableEnum { UE_A, UE_B } __attribute__((unavailable)); // expected-note {{'UnavailableEnum' has been explicitly marked unavailable here}}
+__attribute__((unavailable)) typedef enum UnavailableEnum UnavailableEnum;
+typedef enum UnavailableEnum AnotherUnavailableEnum; // expected-error {{'UnavailableEnum' is unavailable}}
+
+
+__attribute__((unavailable))
+UnavailableEnum testUnavailable(UnavailableEnum X) { return X; }
diff --git a/test/SemaCXX/attr-used.cpp b/test/SemaCXX/attr-used.cpp
index 9bae3ed..65df861 100644
--- a/test/SemaCXX/attr-used.cpp
+++ b/test/SemaCXX/attr-used.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-extern char test1[] __attribute__((used)); // expected-warning {{used attribute ignored}}
-extern const char test2[] __attribute__((used)); // expected-warning {{used attribute ignored}}
+extern char test1[] __attribute__((used)); // expected-warning {{'used' attribute ignored}}
+extern const char test2[] __attribute__((used)); // expected-warning {{'used' attribute ignored}}
extern const char test3[] __attribute__((used)) = "";
diff --git a/test/SemaCXX/attr-weak.cpp b/test/SemaCXX/attr-weak.cpp
index 8939a28..8ba3a95 100644
--- a/test/SemaCXX/attr-weak.cpp
+++ b/test/SemaCXX/attr-weak.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
-namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables and functions}}
+namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables, functions and classes}}
}
namespace {
@@ -31,6 +31,10 @@
};
template <class T>
int Test7<T>::var;
-namespace { class Internal; }
+namespace { class Internal {}; }
template struct Test7<Internal>;
template struct Test7<int>;
+
+class __attribute__((weak)) Test8 {}; // OK
+
+__attribute__((weak)) auto Test9 = Internal(); // expected-error {{weak declaration cannot have internal linkage}}
diff --git a/test/SemaCXX/attr-weakref.cpp b/test/SemaCXX/attr-weakref.cpp
index 0c3f1d2..46ca5ab 100644
--- a/test/SemaCXX/attr-weakref.cpp
+++ b/test/SemaCXX/attr-weakref.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
// GCC will accept anything as the argument of weakref. Should we
// check for an existing decl?
@@ -34,3 +34,5 @@
int a10() __attribute__((weakref ("foo")));
static int v __attribute__((weakref(a1), alias("foo"))); // expected-error {{'weakref' attribute requires a string}}
+
+__attribute__((weakref ("foo"))) auto a11 = 1; // expected-error {{weakref declaration must have internal linkage}}
diff --git a/test/SemaCXX/c99-variable-length-array.cpp b/test/SemaCXX/c99-variable-length-array.cpp
index bb620c7..237f564 100644
--- a/test/SemaCXX/c99-variable-length-array.cpp
+++ b/test/SemaCXX/c99-variable-length-array.cpp
@@ -140,3 +140,24 @@
}
int test = f<int>(0); // expected-note {{instantiation of}}
}
+
+namespace pr18633 {
+ struct A1 {
+ static const int sz;
+ static const int sz2;
+ };
+ const int A1::sz2 = 11;
+ template<typename T>
+ void func () {
+ int arr[A1::sz]; // expected-warning{{variable length arrays are a C99 feature}}
+ }
+ template<typename T>
+ void func2 () {
+ int arr[A1::sz2];
+ }
+ const int A1::sz = 12;
+ void func2() {
+ func<int>();
+ func2<int>();
+ }
+}
diff --git a/test/SemaCXX/calling-conv-compat.cpp b/test/SemaCXX/calling-conv-compat.cpp
index 2d52386..cebac9f 100644
--- a/test/SemaCXX/calling-conv-compat.cpp
+++ b/test/SemaCXX/calling-conv-compat.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fms-extensions -cxx-abi microsoft -verify -triple i686-pc-win32 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fms-extensions -verify -triple i686-pc-win32 %s
// Pointers to free functions
void free_func_default();
@@ -351,24 +351,25 @@
typedef void (__stdcall fun_stdcall)();
typedef void (__fastcall fun_fastcall)();
-// FIXME: Adjust cdecl to thiscall when forming a member pointer.
-//fun_default A::*td1 = &A::method_thiscall;
-fun_cdecl A::*td2 = &A::method_cdecl;
+fun_default A::*td1 = &A::method_thiscall;
+fun_cdecl A::*td2 = &A::method_thiscall;
fun_stdcall A::*td3 = &A::method_stdcall;
fun_fastcall A::*td4 = &A::method_fastcall;
// Round trip the function type through a template, and verify that only cdecl
// gets adjusted.
-template<typename Fn> struct X {
- typedef Fn A::*p;
-};
+template<typename Fn> struct X { typedef Fn A::*p; };
-// FIXME: Adjust cdecl to thiscall when forming a member pointer.
-//X<void ()>::p tmpl1 = &A::method_thiscall;
-//X<void __cdecl ()>::p tmpl2 = &A::method_thiscall;
+X<void ()>::p tmpl1 = &A::method_thiscall;
+X<void __cdecl ()>::p tmpl2 = &A::method_thiscall;
X<void __stdcall ()>::p tmpl3 = &A::method_stdcall;
X<void __fastcall ()>::p tmpl4 = &A::method_fastcall;
+X<fun_default >::p tmpl5 = &A::method_thiscall;
+X<fun_cdecl >::p tmpl6 = &A::method_thiscall;
+X<fun_stdcall >::p tmpl7 = &A::method_stdcall;
+X<fun_fastcall>::p tmpl8 = &A::method_fastcall;
+
} // end namespace MemberPointers
// Test that lambdas that capture nothing convert to cdecl function pointers.
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index 8214f78..ef0a524 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -225,7 +225,7 @@
}
// Test comparison of short to unsigned. If tautological compare does not
-// trigger, then the signed comparision warning will.
+// trigger, then the signed comparison warning will.
void test4(short s) {
// A is max short plus 1. All zero and positive shorts are smaller than it.
// All negative shorts are cast towards the max unsigned range. Relation
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index 5abee4a..538de58 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -75,6 +75,7 @@
int i1 = ToBool() ? 0 : 1;
// p2 (one or both void, and throwing)
+ Fields flds;
i1 ? throw 0 : throw 1;
i1 ? test() : throw 1;
i1 ? throw 0 : test();
@@ -85,8 +86,16 @@
i1 = i1 ? 0 : (throw 0);
i1 ? 0 : test(); // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
i1 ? test() : 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
- (i1 ? throw 0 : i1) = 0; // expected-error {{expression is not assignable}}
- (i1 ? i1 : throw 0) = 0; // expected-error {{expression is not assignable}}
+ (i1 ? throw 0 : i1) = 0;
+ (i1 ? i1 : throw 0) = 0;
+ (i1 ? (throw 0) : i1) = 0;
+ (i1 ? i1 : (throw 0)) = 0;
+ (i1 ? (void)(throw 0) : i1) = 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
+ (i1 ? i1 : (void)(throw 0)) = 0; // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
+ int &throwRef1 = (i1 ? flds.i1 : throw 0);
+ int &throwRef2 = (i1 ? throw 0 : flds.i1);
+ int &throwRef3 = (i1 ? flds.b1 : throw 0); // expected-error {{non-const reference cannot bind to bit-field}}
+ int &throwRef4 = (i1 ? throw 0 : flds.b1); // expected-error {{non-const reference cannot bind to bit-field}}
// p3 (one or both class type, convert to each other)
// b1 (lvalues)
@@ -151,7 +160,6 @@
&(i1 ? i1 : i2); // expected-error {{cannot take the address of an rvalue}}
// p4 (lvalue, same type)
- Fields flds;
int &ir1 = i1 ? flds.i1 : flds.i2;
(i1 ? flds.b1 : flds.i2) = 0;
(i1 ? flds.i1 : flds.b2) = 0;
@@ -219,8 +227,8 @@
// *must* create a separate temporary copy of class objects. This can only
// be properly tested at runtime, though.
- const Abstract &a = true ? static_cast<const Abstract&>(Derived1()) : Derived2(); // expected-error {{allocating an object of abstract class type 'const Abstract'}}
- true ? static_cast<const Abstract&>(Derived1()) : throw 3; // expected-error {{allocating an object of abstract class type 'const Abstract'}}
+ const Abstract &abstract1 = true ? static_cast<const Abstract&>(Derived1()) : Derived2(); // expected-error {{allocating an object of abstract class type 'const Abstract'}}
+ const Abstract &abstract2 = true ? static_cast<const Abstract&>(Derived1()) : throw 3; // ok
}
namespace PR6595 {
@@ -367,3 +375,12 @@
const volatile int &cvir2 = b ? cvi : vi;
const volatile int &cvir3 = b ? ci : vi; // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}}
}
+
+namespace PR17052 {
+ struct X {
+ int i_;
+ bool b_;
+
+ int &test() { return b_ ? i_ : throw 1; }
+ };
+}
diff --git a/test/SemaCXX/const-cast.cpp b/test/SemaCXX/const-cast.cpp
index 1fe350d..cb9937c 100644
--- a/test/SemaCXX/const-cast.cpp
+++ b/test/SemaCXX/const-cast.cpp
@@ -60,7 +60,7 @@
// Function pointers.
f fp2 = const_cast<f>(fp1); // expected-error {{const_cast to 'f' (aka 'int (*)(int)'), which is not a reference, pointer-to-object, or pointer-to-data-member}}
void (A::*mfn)() = 0;
- (void)const_cast<void (A::*)()>(mfn); // expected-error {{const_cast to 'void (A::*)()', which is not a reference, pointer-to-object, or pointer-to-data-member}}
+ (void)const_cast<void (A::*)()>(mfn); // expected-error-re {{const_cast to 'void (A::*)(){{( __attribute__\(\(thiscall\)\))?}}', which is not a reference, pointer-to-object, or pointer-to-data-member}}
(void)const_cast<int&&>(0); // expected-error {{const_cast from rvalue to reference type 'int &&'}} expected-warning {{C++11}}
return **var3;
}
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 6724be7..574e9b3 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment
+// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -Wno-pointer-arith -Wno-zero-length-array -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment -Wno-tautological-pointer-compare -Wno-bool-conversion
namespace StaticAssertFoldTest {
@@ -1863,3 +1863,13 @@
constexpr char d[] = { 'f', 'o', 'o' }; // no nul terminator.
constexpr int bad = __builtin_strlen(d); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
}
+
+namespace PR19010 {
+ struct Empty {};
+ struct Empty2 : Empty {};
+ struct Test : Empty2 {
+ constexpr Test() {}
+ Empty2 array[2];
+ };
+ void test() { constexpr Test t; }
+}
diff --git a/test/SemaCXX/constant-expression.cpp b/test/SemaCXX/constant-expression.cpp
index 942bf41..e01acdd 100644
--- a/test/SemaCXX/constant-expression.cpp
+++ b/test/SemaCXX/constant-expression.cpp
@@ -124,3 +124,20 @@
struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'test3::X'}}
int f() { return Y().b; }
}
+
+// PR18283
+namespace test4 {
+ template <int> struct A {};
+ int const i = { 42 };
+ // i can be used as non-type template-parameter as "const int x = { 42 };" is
+ // equivalent to "const int x = 42;" as per C++03 8.5/p13.
+ typedef A<i> Ai; // ok
+}
+
+// rdar://16064952
+namespace rdar16064952 {
+ template < typename T > void fn1() {
+ T b;
+ unsigned w = ({int a = b.val[sizeof(0)]; 0; }); // expected-warning {{use of GNU statement expression extension}}
+ }
+}
diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp
index e5b7db5..9ad1129 100644
--- a/test/SemaCXX/constexpr-value-init.cpp
+++ b/test/SemaCXX/constexpr-value-init.cpp
@@ -9,7 +9,7 @@
A a;
};
-constexpr A a; // ok, zero initialization preceeds static initialization
+constexpr A a; // ok, zero initialization precedes static initialization
void f() {
constexpr A a; // expected-error {{constant expression}} expected-note {{in call to 'A()'}}
}
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index 1757632..81dc19e 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -94,7 +94,7 @@
Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
Derived::V(),
::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
- INT::NonExisting() {} // expected-error {{expected a class or namespace}} \
+ INT::NonExisting() {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or scoped enumeration}} \
// expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
};
@@ -232,15 +232,14 @@
// <rdar://problem/8308215>: don't crash.
// Lots of questionable recovery here; errors can change.
namespace test3 {
- class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 4 {{candidate}}
+ class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 2 {{candidate}}
class B : public A {
public:
B(const String& s, int e=0) // expected-error {{unknown type name}}
: A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}}
B(const B& e)
: A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} \
- // expected-error {{no member named 'm_String' in 'test3::B'}} \
- // expected-error {{no matching}}
+ // expected-error {{no member named 'm_String' in 'test3::B'}}
}
};
}
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
index 7eaed54..1d5700d 100644
--- a/test/SemaCXX/conversion-function.cpp
+++ b/test/SemaCXX/conversion-function.cpp
@@ -405,3 +405,14 @@
A f(const C c) { return c; }
}
+
+namespace PR18234 {
+ struct A {
+ operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}}
+ operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}}
+ } a;
+ A::S s = a;
+ A::E e = a; // expected-note {{here}}
+ bool k1 = e == A::e; // expected-error {{no member named 'e'}}
+ bool k2 = e.n == 0;
+}
diff --git a/test/SemaCXX/crashes.cpp b/test/SemaCXX/crashes.cpp
index 0b15bb0..1570d12 100644
--- a/test/SemaCXX/crashes.cpp
+++ b/test/SemaCXX/crashes.cpp
@@ -218,3 +218,16 @@
template class basic_stringbuf<char>;
}
+namespace pr16989 {
+ class C {
+ template <class T>
+ C tpl_mem(T *) { return } // expected-error{{expected expression}}
+ void mem(int *p) {
+ tpl_mem(p);
+ }
+ };
+ class C2 {
+ void f();
+ };
+ void C2::f() {}
+}
diff --git a/test/SemaCXX/cstyle-cast.cpp b/test/SemaCXX/cstyle-cast.cpp
index 468c8ec..afac6a1 100644
--- a/test/SemaCXX/cstyle-cast.cpp
+++ b/test/SemaCXX/cstyle-cast.cpp
@@ -227,6 +227,6 @@
void (structure::*psf)() = 0;
(void)(int (structure::*)())(psf);
- (void)(void (structure::*)())(psi); // expected-error {{C-style cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
- (void)(int structure::*)(psf); // expected-error {{C-style cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
+ (void)(void (structure::*)())(psi); // expected-error-re {{C-style cast from 'const int structure::*' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
+ (void)(int structure::*)(psf); // expected-error-re {{C-style cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'int structure::*' is not allowed}}
}
diff --git a/test/SemaCXX/cxx-altivec.cpp b/test/SemaCXX/cxx-altivec.cpp
new file mode 100644
index 0000000..baacbac
--- /dev/null
+++ b/test/SemaCXX/cxx-altivec.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -faltivec -fsyntax-only -verify %s
+
+struct Vector {
+ __vector float xyzw;
+} __attribute__((vecreturn)) __attribute__((vecreturn)); // expected-error {{'vecreturn' attribute cannot be repeated}}
diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
index b1078dc..07a7842 100644
--- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp
+++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
@@ -80,3 +80,7 @@
// (but not normal definitions)
struct S { S(); };
S::S() __attribute((pure)) = default;
+
+using size_t = decltype(sizeof(0));
+void *operator new(size_t) = delete; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}}
+void operator delete(void *) noexcept = delete; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}}
diff --git a/test/SemaCXX/cxx0x-delegating-ctors.cpp b/test/SemaCXX/cxx0x-delegating-ctors.cpp
index a34ee4f..2e1abf5 100644
--- a/test/SemaCXX/cxx0x-delegating-ctors.cpp
+++ b/test/SemaCXX/cxx0x-delegating-ctors.cpp
@@ -43,7 +43,7 @@
}
struct deleted_dtor {
- ~deleted_dtor() = delete; // expected-note{{function has been explicitly marked deleted here}}
+ ~deleted_dtor() = delete; // expected-note{{'~deleted_dtor' has been explicitly marked deleted here}}
deleted_dtor();
deleted_dtor(int) : deleted_dtor() // expected-error{{attempt to use a deleted function}}
{}
diff --git a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
index 0cebc10..b9af679 100644
--- a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
+++ b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
@@ -59,7 +59,7 @@
good_const gc;
struct no_default {
- no_default() = delete; // expected-note 3{{deleted here}}
+ no_default() = delete; // expected-note 4{{deleted here}}
};
struct no_dtor {
~no_dtor() = delete; // expected-note 2{{deleted here}}
@@ -114,7 +114,7 @@
defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}
struct late_delete {
- no_default nd;
+ no_default nd; // expected-note {{because field 'nd' has a deleted default constructor}}
late_delete();
};
late_delete::late_delete() = default; // expected-error {{would delete it}}
diff --git a/test/SemaCXX/cxx0x-type-convert-construct.cpp b/test/SemaCXX/cxx0x-type-convert-construct.cpp
index 6a7fe45..25a43d7 100644
--- a/test/SemaCXX/cxx0x-type-convert-construct.cpp
+++ b/test/SemaCXX/cxx0x-type-convert-construct.cpp
@@ -9,9 +9,9 @@
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}}
+ Rstr = R"foo(a raw string)foo"; // expected-warning{{ISO C++11 does not allow conversion from string literal to 'char *'}}
wchar_t *LRstr;
- LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}}
+ LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{ISO C++11 does not allow conversion from string literal to 'wchar_t *'}}
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;
diff --git a/test/SemaCXX/cxx11-attr-print.cpp b/test/SemaCXX/cxx11-attr-print.cpp
index 01325d3..999eaed 100644
--- a/test/SemaCXX/cxx11-attr-print.cpp
+++ b/test/SemaCXX/cxx11-attr-print.cpp
@@ -42,9 +42,6 @@
// CHECK: {{\[}}[noreturn]];
void f4 [[noreturn]] ();
-// CHECK: {{\[}}[std::noreturn]];
-void f5 [[std::noreturn]] ();
-
// CHECK: __attribute__((gnu_inline));
inline void f6() __attribute__((gnu_inline));
diff --git a/test/SemaCXX/cxx11-gnu-attrs.cpp b/test/SemaCXX/cxx11-gnu-attrs.cpp
index 22d61a1..9f18224 100644
--- a/test/SemaCXX/cxx11-gnu-attrs.cpp
+++ b/test/SemaCXX/cxx11-gnu-attrs.cpp
@@ -19,8 +19,6 @@
void aligned_fn [[gnu::aligned(32)]] ();
struct [[gnu::aligned(8)]] aligned_struct {};
-[[gnu::malloc, gnu::alloc_size(1,2)]] void *alloc_size(int a, int b);
-
void always_inline [[gnu::always_inline]] ();
__thread int tls_model [[gnu::tls_model("local-exec")]];
diff --git a/test/SemaCXX/cxx11-user-defined-literals.cpp b/test/SemaCXX/cxx11-user-defined-literals.cpp
index f8bbcd9..cb77964 100644
--- a/test/SemaCXX/cxx11-user-defined-literals.cpp
+++ b/test/SemaCXX/cxx11-user-defined-literals.cpp
@@ -141,3 +141,27 @@
int operator"" _b(); // expected-error {{no function template matches function template specialization}}
int main() { return 0_b; } // expected-error {{no matching literal operator for call to 'operator "" _b'}}
}
+
+namespace bad_names {
+ template<char...> int operator""_x();
+
+ template<typename T> void f() {
+ class T:: // expected-error {{anonymous class}} expected-warning {{does not declare anything}}
+ operator // expected-error {{expected identifier}}
+ ""_q<'a'>;
+
+ T::template operator""_q<'a'>(); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+ T::template operator""_q<'a'>::X; // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+ T::operator""_q<'a'>(); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+ typename T::template operator""_q<'a'> a; // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+ typename T::operator""_q(""); // expected-error +{{}} expected-note {{to match}}
+ T::operator""_q(""); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}}
+
+ bad_names::operator""_x<'a', 'b', 'c'>();
+ };
+
+ struct S {};
+ void g() {
+ S::operator""_q(); // expected-error {{non-namespace scope 'S::' cannot have a literal operator member}}
+ }
+}
diff --git a/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp
index 20e06f4..dc85748 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -3,6 +3,17 @@
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
+template<class F, class ...Rest> struct first_impl { typedef F type; };
+template<class ...Args> using first = typename first_impl<Args...>::type;
+
+namespace simple_explicit_capture {
+ void test() {
+ int i;
+ auto L = [i](auto a) { return i + a; };
+ L(3.14);
+ }
+}
+
namespace explicit_call {
int test() {
auto L = [](auto a) { return a; };
@@ -489,8 +500,6 @@
template<class ... Ts> void print(Ts ... ts) { }
-template<class F, class ... Rest> using first = F;
-
template<class ... Ts> auto fooV(Ts ... ts) {
auto L = [](auto ... a) {
auto M = [](decltype(a) ... b) {
@@ -560,7 +569,6 @@
namespace variadic_tests_1 {
template<class ... Ts> void print(Ts ... ts) { }
-template<class F, class ... Rest> using FirstType = F;
template<class F, class ... Rest> F& FirstArg(F& f, Rest...) { return f; }
template<class ... Ts> int fooV(Ts ... ts) {
@@ -574,7 +582,7 @@
};
N('a');
N(N);
- N(FirstType<Ts...>{});
+ N(first<Ts...>{});
};
M(a...);
print("a = ", a..., "\n");
@@ -599,7 +607,7 @@
};
N('a');
N(N);
- N(FirstType<Ts...>{});
+ N(first<Ts...>{});
};
M(a...);
return M;
@@ -619,7 +627,7 @@
};
N('a');
N(N);
- N(FirstType<Ts...>{});
+ N(first<Ts...>{});
return N;
};
M(a...);
@@ -763,7 +771,6 @@
namespace fptr_with_decltype_return_type {
-template<class F, class ... Ts> using FirstType = F;
template<class F, class ... Rest> F& FirstArg(F& f, Rest& ... r) { return f; };
template<class ... Ts> auto vfun(Ts&& ... ts) {
print(ts...);
@@ -774,7 +781,7 @@
{
auto L = [](auto ... As) {
return [](auto b) ->decltype(b) {
- vfun([](decltype(As) a) -> decltype(a) { return a; } ...)(FirstType<decltype(As)...>{});
+ vfun([](decltype(As) a) -> decltype(a) { return a; } ...)(first<decltype(As)...>{});
return decltype(b){};
};
};
@@ -905,4 +912,4 @@
-} //end ns inclass_lambdas_within_nested_classes
\ No newline at end of file
+} //end ns inclass_lambdas_within_nested_classes
diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp
index 2cb4d31..64fe50a 100644
--- a/test/SemaCXX/cxx1y-init-captures.cpp
+++ b/test/SemaCXX/cxx1y-init-captures.cpp
@@ -36,7 +36,7 @@
namespace odr_use_within_init_capture {
int test() {
-
+
{ // no captures
const int x = 10;
auto L = [z = x + 2](int a) {
diff --git a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index 94d0f16..1e5e834 100644
--- a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -39,11 +39,11 @@
template<typename T> CONST T B1::right<T,int> = T(5);
class B2 {
- template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous definition is here}}
- template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous definition is here}}
+ template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous initialization is here}}
+ template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous initialization is here}}
};
- template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{redefinition of 'right'}}
- template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{redefinition of 'right'}}
+ template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{static data member 'right' already has an initializer}}
+ template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{static data member 'right' already has an initializer}}
class B3 {
template<typename T, typename T0> static CONST T right = T(100);
@@ -291,6 +291,30 @@
template<typename T> template<typename...U> T A<T>::y<tuple<U...> >[] = { U()... };
static_assert(sizeof(A<int>::y<tuple<char, char, char> >) == 12, "");
}
+
+ namespace bad_reference {
+ struct S {
+ template<typename T> static int A; // expected-note 4{{here}}
+ };
+
+ template<typename T> void f() {
+ typename T::template A<int> a; // expected-error {{template name refers to non-type template 'S::A'}}
+ }
+ template<typename T> void g() {
+ T::template A<int>::B = 0; // expected-error {{template name refers to non-type template 'S::A'}}
+ }
+ template<typename T> void h() {
+ class T::template A<int> c; // expected-error {{template name refers to non-type template 'S::A'}}
+ }
+
+ template<typename T>
+ struct X : T::template A<int> {}; // expected-error {{template name refers to non-type template 'S::A'}}
+
+ template void f<S>(); // expected-note {{in instantiation of}}
+ template void g<S>(); // expected-note {{in instantiation of}}
+ template void h<S>(); // expected-note {{in instantiation of}}
+ template struct X<S>; // expected-note {{in instantiation of}}
+ }
}
namespace in_nested_classes {
diff --git a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
index b6e8762..37d5bf3 100644
--- a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -81,7 +81,7 @@
template<typename T> T v; // expected-note {{previous definition is here}}
template<typename T> int v; // expected-error {{redefinition of 'v'}}
- template<typename T> int v1; // expected-note {{previous template declaration is here}}
+ template<typename T> extern int v1; // expected-note {{previous template declaration is here}}
template<int I> int v1; // expected-error {{template parameter has a different kind in template redeclaration}}
}
namespace pvt_use {
@@ -90,11 +90,8 @@
}
namespace pvt_diff_params {
- // FIXME: (?) Redefinitions should simply be not allowed, whether the
- // template parameters match or not. However, this current behaviour also
- // matches that of class templates...
- template<typename T, typename> T v; // expected-note 2{{previous template declaration is here}}
- template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}}
+ template<typename T, typename> T v; // expected-note {{previous template declaration is here}}
+ template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}} expected-note {{previous template declaration is here}}
template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
}
@@ -391,7 +388,7 @@
namespace n1 {
template<typename T>
- T pi1a = T(3.1415926535897932385);
+ T pi1a = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
#ifndef PRECXX11
// expected-note@-2 {{explicit instantiation refers here}}
#endif
@@ -413,7 +410,7 @@
#endif
float f1 = pi1a<float>;
- template<> double pi1a<double> = 5.2; // expected-error {{no variable template matches specialization}}
+ template<> double pi1a<double> = 5.2; // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}}
double d1 = pi1a<double>;
}
@@ -432,3 +429,22 @@
}
}
+namespace nested_name {
+ template<typename T> int a; // expected-note {{variable template 'a' declared here}}
+ a<int>::b c; // expected-error {{qualified name refers into a specialization of variable template 'a'}}
+
+ class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
+ enum a<int> {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}}
+}
+
+namespace PR18530 {
+ template<typename T> int a;
+ int a<int>; // expected-error {{requires 'template<>'}}
+}
+
+namespace PR19152 {
+#ifndef PRECXX11
+ template<typename T> const auto x = 1;
+ static_assert(x<int> == 1, "");
+#endif
+}
diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp
index 9690638..8c1efc9 100644
--- a/test/SemaCXX/cxx98-compat.cpp
+++ b/test/SemaCXX/cxx98-compat.cpp
@@ -23,7 +23,7 @@
class Variadic3 {};
alignas(8) int with_alignas; // expected-warning {{'alignas' is incompatible with C++98}}
-int with_attribute [[ ]]; // expected-warning {{attributes are incompatible with C++98}}
+int with_attribute [[ ]]; // expected-warning {{C++11 attribute syntax is incompatible with C++98}}
void Literals() {
(void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}}
@@ -219,18 +219,11 @@
class PrivateMember {
struct ImPrivate {};
};
-template<typename T> typename T::ImPrivate SFINAEAccessControl(T t) { // expected-warning {{substitution failure due to access control is incompatible with C++98}} expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}}
+template<typename T> typename T::ImPrivate SFINAEAccessControl(T t) { // expected-warning {{substitution failure due to access control is incompatible with C++98}}
return typename T::ImPrivate();
}
int SFINAEAccessControl(...) { return 0; }
-int CheckSFINAEAccessControl = SFINAEAccessControl(PrivateMember());
-
-template<typename T>
-struct FriendRedefinition {
- friend void Friend() {} // expected-warning {{friend function 'Friend' would be implicitly redefined in C++98}} expected-note {{previous}}
-};
-FriendRedefinition<int> FriendRedef1;
-FriendRedefinition<char> FriendRedef2; // expected-note {{requested here}}
+int CheckSFINAEAccessControl = SFINAEAccessControl(PrivateMember()); // expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}}
namespace CopyCtorIssues {
struct Private {
diff --git a/test/SemaCXX/decl-microsoft-call-conv.cpp b/test/SemaCXX/decl-microsoft-call-conv.cpp
index 9f14632..4282047 100644
--- a/test/SemaCXX/decl-microsoft-call-conv.cpp
+++ b/test/SemaCXX/decl-microsoft-call-conv.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -fms-extensions -verify %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -verify %s
typedef void void_fun_t();
typedef void __cdecl cdecl_fun_t();
@@ -191,3 +191,41 @@
};
extern template void valarray<int>::bar();
}
+
+namespace test6 {
+ struct foo {
+ int bar();
+ };
+ typedef int bar_t();
+ void zed(bar_t foo::*) {
+ }
+ void baz() {
+ zed(&foo::bar);
+ }
+}
+
+namespace test7 {
+ template <typename T>
+ struct S {
+ void f(T t) {
+ t = 42;
+ }
+ };
+ template<> void S<void*>::f(void*);
+ void g(S<void*> s, void* p) {
+ s.f(p);
+ }
+}
+
+namespace test8 {
+ template <typename T>
+ struct S {
+ void f(T t) { // expected-note {{previous declaration is here}}
+ t = 42; // expected-error {{assigning to 'void *' from incompatible type 'int'}}
+ }
+ };
+ template<> void __cdecl S<void*>::f(void*); // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
+ void g(S<void*> s, void* p) {
+ s.f(p); // expected-note {{in instantiation of member function 'test8::S<void *>::f' requested here}}
+ }
+}
diff --git a/test/SemaCXX/decltype.cpp b/test/SemaCXX/decltype.cpp
index d6e85d2..8de5a9c 100644
--- a/test/SemaCXX/decltype.cpp
+++ b/test/SemaCXX/decltype.cpp
@@ -45,6 +45,16 @@
U &r = S<int>::f();
}
+namespace PR18876 {
+ struct A { ~A() = delete; }; // expected-note +{{here}}
+ A f();
+ decltype(f()) *a; // ok, function call
+ decltype(A()) *b; // expected-error {{attempt to use a deleted function}}
+ decltype(0, f()) *c; // ok, function call on RHS of comma
+ decltype(0, A()) *d; // expected-error {{attempt to use a deleted function}}
+ decltype(f(), 0) *e; // expected-error {{attempt to use a deleted function}}
+}
+
template<typename>
class conditional {
};
diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp
index e78e7ed..d7ef9b2 100644
--- a/test/SemaCXX/deleted-function.cpp
+++ b/test/SemaCXX/deleted-function.cpp
@@ -15,9 +15,9 @@
void ov(double) = delete; // expected-note {{candidate function has been explicitly deleted}}
struct WithDel {
- WithDel() = delete; // expected-note {{function has been explicitly marked deleted here}}
- void fn() = delete; // expected-note {{function has been explicitly marked deleted here}}
- operator int() = delete; // expected-note {{function has been explicitly marked deleted here}}
+ WithDel() = delete; // expected-note {{'WithDel' has been explicitly marked deleted here}}
+ void fn() = delete; // expected-note {{'fn' has been explicitly marked deleted here}}
+ operator int() = delete; // expected-note {{'operator int' has been explicitly marked deleted here}}
void operator +(int) = delete;
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
index 9f53e71..df67978 100644
--- a/test/SemaCXX/deleted-operator.cpp
+++ b/test/SemaCXX/deleted-operator.cpp
@@ -13,6 +13,7 @@
}
struct DelOpDel {
- virtual ~DelOpDel() {} // expected-error {{deleted function}}
- void operator delete(void*) = delete; // expected-note {{deleted here}}
+ // FIXME: In MS ABI, we error twice below.
+ virtual ~DelOpDel() {} // expected-error 1-2 {{attempt to use a deleted function}}
+ void operator delete(void*) = delete; // expected-note 1-2 {{deleted here}}
};
diff --git a/test/SemaCXX/deprecated.cpp b/test/SemaCXX/deprecated.cpp
index 0335a80..2fe6d59 100644
--- a/test/SemaCXX/deprecated.cpp
+++ b/test/SemaCXX/deprecated.cpp
@@ -24,12 +24,15 @@
register int m asm("rbx"); // no-warning
int k = to_int(n); // no-warning
-
bool b;
++b; // expected-warning {{incrementing expression of type bool is deprecated}}
- // FIXME: This is ill-formed in C++11.
- char *p = "foo"; // expected-warning {{conversion from string literal to 'char *' is deprecated}}
+ char *p = "foo";
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#else
+ // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
+#endif
}
struct S { int n; };
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index e511be0..7642228 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple %ms_abi_triple -DMSABI -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
class A {
public:
~A();
@@ -83,6 +84,12 @@
}
namespace PR6709 {
+#ifdef MSABI
+ // This bug, "Clang instantiates destructor for function argument" is intended
+ // behaviour in the Microsoft ABI because the callee needs to destruct the arguments.
+ // expected-error@+3 {{indirection requires pointer operand ('int' invalid)}}
+ // expected-note@+3 {{in instantiation of member function 'PR6709::X<int>::~X' requested here}}
+#endif
template<class T> class X { T v; ~X() { ++*v; } };
void a(X<int> x) {}
}
@@ -100,10 +107,16 @@
T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
}
+#ifdef MSABI
+ // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
+#endif
virtual ~A() {}
};
- class B : A<int> { B(); }; // expected-note {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
+#ifndef MSABI
+ // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
+#endif
+ class B : A<int> { B(); };
B::B() {}
}
diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp
new file mode 100644
index 0000000..3558eef
--- /dev/null
+++ b/test/SemaCXX/dllexport.cpp
@@ -0,0 +1,251 @@
+// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Exported {};
+struct ExplicitDecl_Exported {};
+struct ExplicitInst_Exported {};
+struct ExplicitSpec_Exported {};
+struct ExplicitSpec_Def_Exported {};
+struct ExplicitSpec_InlineDef_Exported {};
+struct ExplicitSpec_NotExported {};
+namespace { struct Internal {}; }
+struct External { int v; };
+
+
+// Invalid usage.
+__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+#if __has_feature(cxx_strong_enums)
+ enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+#endif
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Export declaration.
+__declspec(dllexport) extern int ExternGlobalDecl;
+
+// dllexport implies a definition.
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+__declspec(dllexport) int GlobalInit1 = 1;
+int __declspec(dllexport) GlobalInit2 = 1;
+
+// Declare, then export definition.
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Redeclarations
+__declspec(dllexport) extern int GlobalRedecl1;
+__declspec(dllexport) int GlobalRedecl1;
+
+__declspec(dllexport) extern int GlobalRedecl2;
+ int GlobalRedecl2;
+
+ extern int GlobalRedecl3; // expected-note{{previous declaration is here}}
+__declspec(dllexport) extern int GlobalRedecl3; // expected-error{{redeclaration of 'GlobalRedecl3' cannot add 'dllexport' attribute}}
+
+// External linkage is required.
+__declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}
+__declspec(dllexport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllexport'}}
+namespace { __declspec(dllexport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllexport'}}
+namespace ns { __declspec(dllexport) int ExternalGlobal; }
+
+__declspec(dllexport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllexport'}}
+__declspec(dllexport) auto ExternalAutoTypeGlobal = External();
+
+// Export in local scope.
+void functionScope() {
+ __declspec(dllexport) int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}}
+ __declspec(dllexport) int LocalVarDef = 1; // expected-error{{'LocalVarDef' must have external linkage when declared 'dllexport'}}
+ __declspec(dllexport) extern int ExternLocalVarDecl;
+ __declspec(dllexport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllexport'}}
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Export function declaration. Check different placements.
+__attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllexport) void decl1B();
+
+void __attribute__((dllexport)) decl2A();
+void __declspec(dllexport) decl2B();
+
+// Export function definition.
+__declspec(dllexport) void def() {}
+
+// extern "C"
+extern "C" __declspec(dllexport) void externC() {}
+
+// Export inline function.
+__declspec(dllexport) inline void inlineFunc1() {} // expected-warning{{'dllexport' attribute ignored}}
+inline void __attribute__((dllexport)) inlineFunc2() {} // expected-warning{{'dllexport' attribute ignored}}
+
+__declspec(dllexport) inline void inlineDecl(); // expected-warning{{'dllexport' attribute ignored}}
+ void inlineDecl() {}
+
+__declspec(dllexport) void inlineDef();
+ inline void inlineDef() {}
+
+// Redeclarations
+__declspec(dllexport) void redecl1();
+__declspec(dllexport) void redecl1() {}
+
+__declspec(dllexport) void redecl2();
+ void redecl2() {}
+
+ void redecl3(); // expected-note{{previous declaration is here}}
+__declspec(dllexport) void redecl3(); // expected-error{{redeclaration of 'redecl3' cannot add 'dllexport' attribute}}
+
+// Friend functions
+struct FuncFriend {
+ friend __declspec(dllexport) void friend1();
+ friend __declspec(dllexport) void friend2();
+ friend void friend3(); // expected-note{{previous declaration is here}}
+};
+__declspec(dllexport) void friend1() {}
+ void friend2() {}
+__declspec(dllexport) void friend3() {} // expected-error{{redeclaration of 'friend3' cannot add 'dllexport' attribute}}
+
+// Implicit declarations can be redeclared with dllexport.
+__declspec(dllexport) void* operator new(__SIZE_TYPE__ n);
+
+// External linkage is required.
+__declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}}
+__declspec(dllexport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllexport'}}
+namespace { __declspec(dllexport) void internalFunc() {} } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllexport'}}
+namespace ns { __declspec(dllexport) void externalFunc() {} }
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Export function template declaration. Check different placements.
+template<typename T> __declspec(dllexport) void funcTmplDecl1();
+template<typename T> void __declspec(dllexport) funcTmplDecl2();
+
+// Export function template definition.
+template<typename T> __declspec(dllexport) void funcTmplDef() {}
+
+// Redeclarations
+template<typename T> __declspec(dllexport) void funcTmplRedecl1();
+template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
+
+template<typename T> __declspec(dllexport) void funcTmplRedecl2();
+template<typename T> void funcTmplRedecl2() {}
+
+template<typename T> void funcTmplRedecl3(); // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllexport) void funcTmplRedecl3(); // expected-error{{redeclaration of 'funcTmplRedecl3' cannot add 'dllexport' attribute}}
+
+// Function template friends
+struct FuncTmplFriend {
+ template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
+ template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
+ template<typename T> friend void funcTmplFriend3(); // expected-note{{previous declaration is here}}
+};
+template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
+template<typename T> void funcTmplFriend2() {}
+template<typename T> __declspec(dllexport) void funcTmplFriend3() {} // expected-error{{redeclaration of 'funcTmplFriend3' cannot add 'dllexport' attribute}}
+
+// External linkage is required.
+template<typename T> __declspec(dllexport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllexport'}}
+template<typename T> __declspec(dllexport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllexport'}}
+namespace { template<typename T> __declspec(dllexport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllexport'}}
+namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl(); }
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> __declspec(dllexport) void exportedFuncTmplDecl();
+template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
+
+// Export implicit instantiation of an exported function template.
+void useFunTmplDecl() { exportedFuncTmplDecl<ImplicitInst_Exported>(); }
+void useFunTmplDef() { exportedFuncTmpl<ImplicitInst_Exported>(); }
+
+// Export explicit instantiation declaration of an exported function template.
+extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
+ template void exportedFuncTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of an exported function template.
+template void exportedFuncTmpl<ExplicitInst_Exported>();
+
+// Export specialization of an exported function template.
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {} // expected-warning{{'dllexport' attribute ignored}}
+
+// Not exporting specialization of an exported function template without
+// explicit dllexport.
+template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported function template.
+extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+ template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of a non-exported function template.
+template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
+
+// Export specialization of a non-exported function template.
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {} // expected-warning{{'dllexport' attribute ignored}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over dllimport if both are specified.
+__attribute__((dllimport, dllexport)) extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport)) extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
+
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport) int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) int PrecedenceGlobalRedecl2;
+
+void __attribute__((dllimport, dllexport)) precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __attribute__((dllexport, dllimport)) precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) precedenceRedecl1() {}
+
+void __declspec(dllexport) precedenceRedecl2();
+void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp
new file mode 100644
index 0000000..95e9e7d
--- /dev/null
+++ b/test/SemaCXX/dllimport.cpp
@@ -0,0 +1,227 @@
+// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Imported {};
+struct ExplicitDecl_Imported {};
+struct ExplicitInst_Imported {};
+struct ExplicitSpec_Imported {};
+struct ExplicitSpec_Def_Imported {};
+struct ExplicitSpec_InlineDef_Imported {};
+struct ExplicitSpec_NotImported {};
+namespace { struct Internal {}; }
+
+
+// Invalid usage.
+__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+enum __declspec(dllimport) Enum {}; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+#if __has_feature(cxx_strong_enums)
+ enum class __declspec(dllimport) EnumClass {}; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+#endif
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+__declspec(dllimport) extern int ExternGlobalDecl;
+
+// dllimport implies a declaration.
+__declspec(dllimport) int GlobalDecl;
+int **__attribute__((dllimport))* GlobalDeclChunkAttr;
+int GlobalDeclAttr __attribute__((dllimport));
+
+// Not allowed on definitions.
+__declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}}
+__declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}}
+int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}
+
+// Declare, then reject definition.
+__declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int ExternGlobalDeclInit = 1; // expected-warning{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+__declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int GlobalDeclInit = 1; // expected-warning{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int *GlobalDeclChunkAttrInit = 0; // expected-warning{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int GlobalDeclAttrInit = 1; // expected-warning{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+// Redeclarations
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+
+__declspec(dllimport) int GlobalRedecl2a;
+__declspec(dllimport) int GlobalRedecl2a;
+
+int *__attribute__((dllimport)) GlobalRedecl2b;
+int *__attribute__((dllimport)) GlobalRedecl2b;
+
+int GlobalRedecl2c __attribute__((dllimport));
+int GlobalRedecl2c __attribute__((dllimport));
+
+// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+__declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+ extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
+__declspec(dllimport) extern int GlobalRedecl4; // expected-error{{redeclaration of 'GlobalRedecl4' cannot add 'dllimport' attribute}}
+
+// External linkage is required.
+__declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}
+__declspec(dllimport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}}
+namespace { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}}
+namespace ns { __declspec(dllimport) int ExternalGlobal; }
+
+__declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}}
+ // expected-error@-1{{definition of dllimport data}}
+
+// Import in local scope.
+__declspec(dllimport) float LocalRedecl1; // expected-note{{previous definition is here}}
+__declspec(dllimport) float LocalRedecl2; // expected-note{{previous definition is here}}
+__declspec(dllimport) float LocalRedecl3; // expected-note{{previous definition is here}}
+void functionScope() {
+ __declspec(dllimport) int LocalRedecl1; // expected-error{{redefinition of 'LocalRedecl1' with a different type: 'int' vs 'float'}}
+ int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redefinition of 'LocalRedecl2' with a different type: 'int *' vs 'float'}}
+ int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redefinition of 'LocalRedecl3' with a different type: 'int' vs 'float'}}
+
+ __declspec(dllimport) int LocalVarDecl;
+ __declspec(dllimport) int LocalVarDef = 1; // expected-error{{definition of dllimport data}}
+ __declspec(dllimport) extern int ExternLocalVarDecl;
+ __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}}
+ __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}}
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Import function declaration. Check different placements.
+__attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllimport) void decl1B();
+
+void __attribute__((dllimport)) decl2A();
+void __declspec(dllimport) decl2B();
+
+// Not allowed on function definitions.
+__declspec(dllimport) void def() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
+
+// extern "C"
+extern "C" __declspec(dllexport) void externC();
+
+// Import inline function.
+__declspec(dllimport) inline void inlineFunc1() {} // expected-warning{{'dllimport' attribute ignored}}
+inline void __attribute__((dllimport)) inlineFunc2() {} // expected-warning{{'dllimport' attribute ignored}}
+
+// Redeclarations
+__declspec(dllimport) void redecl1();
+__declspec(dllimport) void redecl1();
+
+// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+__declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+__declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+ void redecl4(); // expected-note{{previous declaration is here}}
+__declspec(dllimport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllimport' attribute}}
+
+// Friend functions
+struct FuncFriend {
+ friend __declspec(dllimport) void friend1();
+ friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ friend void friend4(); // expected-note{{previous declaration is here}}
+};
+__declspec(dllimport) void friend1();
+ void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+ void friend3() {} // expected-warning{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+__declspec(dllimport) void friend4(); // expected-error{{redeclaration of 'friend4' cannot add 'dllimport' attribute}}
+
+// Implicit declarations can be redeclared with dllimport.
+__declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
+
+// External linkage is required.
+__declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}
+__declspec(dllimport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllimport'}}
+namespace { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}
+namespace ns { __declspec(dllimport) void externalFunc(); }
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Import function template declaration. Check different placements.
+template<typename T> __declspec(dllimport) void funcTmplDecl1();
+template<typename T> void __declspec(dllimport) funcTmplDecl2();
+
+// Redeclarations
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+
+template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T> void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T> void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T> void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}}
+
+// Function template friends
+struct FuncTmplFriend {
+ template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
+ template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+ template<typename T> friend void funcTmplFriend4(); // expected-note{{previous declaration is here}}
+};
+template<typename T> __declspec(dllimport) void funcTmplFriend1();
+template<typename T> void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}}
+
+// External linkage is required.
+template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}}
+template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}}
+namespace { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}}
+namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> __declspec(dllimport) void importedFuncTmpl();
+
+// Import specialization of an imported function template. A definition must be
+// declared inline.
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
+template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {} // expected-warning{{'dllimport' attribute ignored}}
+
+// Not importing specialization of an imported function template without
+// explicit dllimport.
+template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
+
+
+// Import explicit instantiation declaration of a non-imported function template.
+extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
+
+// Import specialization of a non-imported function template. A definition must
+// be declared inline.
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
+template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {} // expected-warning{{'dllimport' attribute ignored}}
diff --git a/test/SemaCXX/enable_if.cpp b/test/SemaCXX/enable_if.cpp
new file mode 100644
index 0000000..e9dc242
--- /dev/null
+++ b/test/SemaCXX/enable_if.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+typedef int (*fp)(int);
+int surrogate(int);
+
+struct X {
+ X() = default; // expected-note{{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+ X(const X&) = default; // expected-note{{candidate constructor not viable: no known conversion from 'bool' to 'const X' for 1st argument}}
+ X(bool b) __attribute__((enable_if(b, "chosen when 'b' is true"))); // expected-note{{candidate disabled: chosen when 'b' is true}}
+
+ void f(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero")));
+ void f(int n) __attribute__((enable_if(n == 1, "chosen when 'n' is one"))); // expected-note{{member declaration nearly matches}} expected-note{{candidate disabled: chosen when 'n' is one}}
+
+ static void s(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))); // expected-note2{{candidate disabled: chosen when 'n' is zero}}
+
+ void conflict(int n) __attribute__((enable_if(n+n == 10, "chosen when 'n' is five"))); // expected-note{{candidate function}}
+ void conflict(int n) __attribute__((enable_if(n*2 == 10, "chosen when 'n' is five"))); // expected-note{{candidate function}}
+
+ operator long() __attribute__((enable_if(true, "chosen on your platform")));
+ operator int() __attribute__((enable_if(false, "chosen on other platform")));
+
+ operator fp() __attribute__((enable_if(false, "never enabled"))) { return surrogate; } // expected-note{{conversion candidate of type 'int (*)(int)'}} // FIXME: the message is not displayed
+};
+
+void X::f(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))) // expected-note{{member declaration nearly matches}} expected-note{{candidate disabled: chosen when 'n' is zero}}
+{
+}
+
+void X::f(int n) __attribute__((enable_if(n == 2, "chosen when 'n' is two"))) // expected-error{{out-of-line definition of 'f' does not match any declaration in 'X'}} expected-note{{candidate disabled: chosen when 'n' is two}}
+{
+}
+
+X x1(true);
+X x2(false); // expected-error{{no matching constructor for initialization of 'X'}}
+
+__attribute__((deprecated)) constexpr int old() { return 0; } // expected-note2{{'old' has been explicitly marked deprecated here}}
+void deprec1(int i) __attribute__((enable_if(old() == 0, "chosen when old() is zero"))); // expected-warning{{'old' is deprecated}}
+void deprec2(int i) __attribute__((enable_if(old() == 0, "chosen when old() is zero"))); // expected-warning{{'old' is deprecated}}
+
+void overloaded(int);
+void overloaded(long);
+
+struct Nothing { };
+template<typename T> void typedep(T t) __attribute__((enable_if(t, ""))); // expected-note{{candidate disabled:}} expected-error{{value of type 'Nothing' is not contextually convertible to 'bool'}}
+template<int N> void valuedep() __attribute__((enable_if(N == 1, "")));
+
+// FIXME: we skip potential constant expression evaluation on value dependent
+// enable-if expressions
+int not_constexpr();
+template<int N> void valuedep() __attribute__((enable_if(N == not_constexpr(), "")));
+
+template <typename T> void instantiationdep() __attribute__((enable_if(sizeof(sizeof(T)) != 0, "")));
+
+void test() {
+ X x;
+ x.f(0);
+ x.f(1);
+ x.f(2); // no error, suppressed by erroneous out-of-line definition
+ x.f(3); // expected-error{{no matching member function for call to 'f'}}
+
+ x.s(0);
+ x.s(1); // expected-error{{no matching member function for call to 's'}}
+
+ X::s(0);
+ X::s(1); // expected-error{{no matching member function for call to 's'}}
+
+ x.conflict(5); // expected-error{{call to member function 'conflict' is ambiguous}}
+
+ deprec2(0);
+
+ overloaded(x);
+
+ int i = x(1); // expected-error{{no matching function for call to object of type 'X'}}
+
+ Nothing n;
+ typedep(0); // expected-error{{no matching function for call to 'typedep'}}
+ typedep(1);
+ typedep(n); // expected-note{{in instantiation of function template specialization 'typedep<Nothing>' requested here}}
+}
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index b4aad18..1eed228 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -78,22 +78,22 @@
// All the redeclarations below are done twice on purpose. Tests that the type
// of the declaration isn't changed.
-enum class Redeclare2; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum class Redeclare2; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
enum Redeclare2; // expected-error{{previously declared as scoped}}
enum Redeclare2; // expected-error{{previously declared as scoped}}
-enum Redeclare3 : int; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum Redeclare3 : int; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
enum Redeclare3; // expected-error{{previously declared with fixed underlying type}}
enum Redeclare3; // expected-error{{previously declared with fixed underlying type}}
enum class Redeclare5;
enum class Redeclare5 : int; // ok
-enum Redeclare6 : int; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum Redeclare6 : int; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
enum Redeclare6 : short; // expected-error{{redeclared with different underlying type}}
enum Redeclare6 : short; // expected-error{{redeclared with different underlying type}}
-enum class Redeclare7; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum class Redeclare7; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}}
enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}}
@@ -272,6 +272,11 @@
A f(A a) { return -a; } // expected-error {{invalid argument type 'PR16900::A' to unary expression}}
}
+namespace PR18551 {
+ enum class A { A };
+ bool f() { return !A::A; } // expected-error {{invalid argument type 'PR18551::A' to unary expression}}
+}
+
namespace rdar15124329 {
enum class B : bool { F, T };
diff --git a/test/SemaCXX/explicit.cpp b/test/SemaCXX/explicit.cpp
index 1c4d770..aa28bd8 100644
--- a/test/SemaCXX/explicit.cpp
+++ b/test/SemaCXX/explicit.cpp
@@ -246,3 +246,8 @@
explicit explicit Test(int x); // expected-warning{{duplicate 'explicit' declaration specifier}}
};
}
+
+namespace PR18777 {
+ struct S { explicit operator bool() const; } s;
+ int *p = new int(s); // expected-error {{no viable conversion}}
+}
diff --git a/test/SemaCXX/expression-traits.cpp b/test/SemaCXX/expression-traits.cpp
index 3a00687..51bb90e 100644
--- a/test/SemaCXX/expression-traits.cpp
+++ b/test/SemaCXX/expression-traits.cpp
@@ -520,20 +520,19 @@
// 5.16 Conditional operator [expr.cond]
//
// 2 If either the second or the third operand has type (possibly
- // cv-qualified) void, then the lvalue-to-rvalue (4.1),
- // array-to-pointer (4.2), and function-to-pointer (4.3) standard
- // conversions are performed on the second and third operands, and one
- // of the following shall hold:
+ // cv-qualified) void, one of the following shall hold:
//
// - 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.
+ // (possibly parenthesized) throw-expression (15.1); the result
+ // is of the type and value category of the other.
Class classLvalue;
ASSERT_RVALUE(cond ? throw 1 : (void)0);
ASSERT_RVALUE(cond ? (void)0 : throw 1);
- ASSERT_RVALUE(cond ? throw 1 : classLvalue);
- ASSERT_RVALUE(cond ? classLvalue : throw 1);
+ ASSERT_RVALUE(cond ? throw 1 : 0);
+ ASSERT_RVALUE(cond ? 0 : throw 1);
+ ASSERT_LVALUE(cond ? throw 1 : classLvalue);
+ ASSERT_LVALUE(cond ? classLvalue : throw 1);
// - 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
diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp
index 2635fb8..25a9c84 100644
--- a/test/SemaCXX/expressions.cpp
+++ b/test/SemaCXX/expressions.cpp
@@ -118,3 +118,10 @@
(void)s1.foo();
(void)s2.foo();
}
+
+namespace pr16992 {
+ typedef int T;
+ unsigned getsz() {
+ return (sizeof T());
+ }
+}
diff --git a/test/SemaCXX/flexible-array-test.cpp b/test/SemaCXX/flexible-array-test.cpp
index f287711..e58f19a 100644
--- a/test/SemaCXX/flexible-array-test.cpp
+++ b/test/SemaCXX/flexible-array-test.cpp
@@ -36,14 +36,20 @@
}
struct S {
- virtual void foo();
+ virtual void foo();
};
struct X {
int blah;
- S strings[]; // expected-error {{flexible array member 'strings' of non-POD element type 'S []'}}
+ S strings[];
};
+S a, b = a;
+S f(X &x) {
+ a = b;
+ return x.strings[0];
+}
+
class A {
int s;
char c[];
@@ -71,3 +77,14 @@
};
}
+
+struct NonTrivDtor { ~NonTrivDtor(); };
+// FIXME: It's not clear whether we should disallow examples like this. GCC accepts.
+struct FlexNonTrivDtor {
+ int n;
+ NonTrivDtor ntd[]; // expected-error {{flexible array member 'ntd' of type 'NonTrivDtor []' with non-trivial destruction}}
+ ~FlexNonTrivDtor() {
+ for (int i = n; i != 0; --i)
+ ntd[i-1].~NonTrivDtor();
+ }
+};
diff --git a/test/SemaCXX/for-range-dereference.cpp b/test/SemaCXX/for-range-dereference.cpp
index bf3187d..7377199 100644
--- a/test/SemaCXX/for-range-dereference.cpp
+++ b/test/SemaCXX/for-range-dereference.cpp
@@ -11,7 +11,7 @@
struct DeletedEnd : public T {
Data *begin();
- Data *end() = delete; //expected-note {{function has been explicitly marked deleted here}}
+ Data *end() = delete; //expected-note {{'end' has been explicitly marked deleted here}}
};
struct DeletedADLBegin { };
diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp
index f8e0c46..f5ca76c 100644
--- a/test/SemaCXX/functional-cast.cpp
+++ b/test/SemaCXX/functional-cast.cpp
@@ -305,8 +305,8 @@
(void)structureimfp(psf);
typedef void (structure::*structurevmfp)();
- (void)structurevmfp(psi); // expected-error {{functional-style cast from 'const int structure::*' to 'structurevmfp' (aka 'void (structure::*)()') is not allowed}}
- (void)structureimp(psf); // expected-error {{functional-style cast from 'void (structure::*)()' to 'structureimp' (aka 'int structure::*') is not allowed}}
+ (void)structurevmfp(psi); // expected-error-re {{functional-style cast from 'const int structure::*' to 'structurevmfp' (aka 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}') is not allowed}}
+ (void)structureimp(psf); // expected-error-re {{functional-style cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'structureimp' (aka 'int structure::*') is not allowed}}
}
// ---------------- misc ------------------
diff --git a/test/SemaCXX/goto.cpp b/test/SemaCXX/goto.cpp
index 24bcb7c..042ec3c 100644
--- a/test/SemaCXX/goto.cpp
+++ b/test/SemaCXX/goto.cpp
@@ -118,7 +118,7 @@
namespace test12 {
struct A { A(); A(const A&); ~A(); };
- void test(A a) { // expected-note {{jump enters lifetime of block}} FIXME: wierd location
+ void test(A a) { // expected-note {{jump enters lifetime of block}} FIXME: weird location
goto lbl; // expected-error {{goto into protected scope}}
(void) ^{ (void) a; };
lbl:
diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp
index b5f7fe1..de679fe 100644
--- a/test/SemaCXX/implicit-member-functions.cpp
+++ b/test/SemaCXX/implicit-member-functions.cpp
@@ -58,13 +58,13 @@
};
struct B;
struct A {
+ // expected-note@-1 {{while substituting deduced template arguments}}
typedef B type;
template<typename T,
typename = typename InvokeCopyConstructor<typename T::type>::type>
// expected-note@-1 {{in instantiation of template class}}
A(const T &);
// expected-note@-1 {{in instantiation of default argument}}
- // expected-note@-2 {{while substituting deduced template arguments}}
};
struct B { // expected-note {{candidate constructor (the implicit move }}
B(); // expected-note {{candidate constructor not viable}}
diff --git a/test/SemaCXX/implicit-virtual-member-functions.cpp b/test/SemaCXX/implicit-virtual-member-functions.cpp
index cd547f5..f88a55c 100644
--- a/test/SemaCXX/implicit-virtual-member-functions.cpp
+++ b/test/SemaCXX/implicit-virtual-member-functions.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %s
struct A {
virtual ~A();
};
@@ -9,8 +10,12 @@
void operator delete (void *, int); // expected-note {{'operator delete' declared here}}
};
+#ifdef MSABI
+B b; // expected-note {{implicit destructor for 'B' first required here}}
+#else
void B::f() { // expected-note {{implicit destructor for 'B' first required here}}
}
+#endif
struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
C();
@@ -26,4 +31,3 @@
void f() {
new D; // expected-note {{implicit destructor for 'D' first required here}}
}
-
diff --git a/test/SemaCXX/init-priority-attr.cpp b/test/SemaCXX/init-priority-attr.cpp
index a91eb60..a2e6df2 100644
--- a/test/SemaCXX/init-priority-attr.cpp
+++ b/test/SemaCXX/init-priority-attr.cpp
@@ -25,8 +25,7 @@
Two koo[4] __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires an integer constant}}
-
-Two func() __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
+Two func() __attribute__((init_priority(1001))); // expected-error {{'init_priority' attribute only applies to variables}}
int i __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index e290424..9a53e46 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -282,4 +282,84 @@
};
L l;
}
-}
\ No newline at end of file
+}
+
+// PR18477: don't try to capture 'this' from an NSDMI encountered while parsing
+// a lambda.
+namespace NSDMIs_in_lambdas {
+ template<typename T> struct S { int a = 0; int b = a; };
+ void f() { []() { S<int> s; }; }
+
+ auto x = []{ struct S { int n, m = n; }; };
+ auto y = [&]{ struct S { int n, m = n; }; }; // expected-error {{non-local lambda expression cannot have a capture-default}}
+ void g() { auto z = [&]{ struct S { int n, m = n; }; }; }
+}
+
+namespace CaptureIncomplete {
+ struct Incomplete; // expected-note 2{{forward decl}}
+ void g(const Incomplete &a);
+ void f(Incomplete &a) {
+ (void) [a] {}; // expected-error {{incomplete}}
+ (void) [&a] {};
+
+ (void) [=] { g(a); }; // expected-error {{incomplete}}
+ (void) [&] { f(a); };
+ }
+}
+
+namespace CaptureAbstract {
+ struct S {
+ virtual void f() = 0; // expected-note {{unimplemented}}
+ int n = 0;
+ };
+ struct T : S {
+ constexpr T() {}
+ void f();
+ };
+ void f() {
+ constexpr T t = T();
+ S &s = const_cast<T&>(t);
+ // FIXME: Once we properly compute odr-use per DR712, this should be
+ // accepted (and should not capture 's').
+ [=] { return s.n; }; // expected-error {{abstract}}
+ }
+}
+
+namespace PR18128 {
+ auto l = [=]{}; // expected-error {{non-local lambda expression cannot have a capture-default}}
+
+ struct S {
+ int n;
+ int (*f())[true ? 1 : ([=]{ return n; }(), 0)];
+ // expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
+ // expected-error@-2 {{invalid use of non-static data member 'n'}}
+ // expected-error@-3 {{a lambda expression may not appear inside of a constant expression}}
+ int g(int k = ([=]{ return n; }(), 0));
+ // expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
+ // expected-error@-2 {{invalid use of non-static data member 'n'}}
+
+ int a = [=]{ return n; }(); // ok
+ int b = [=]{ return [=]{ return n; }(); }(); // ok
+ int c = []{ int k = 0; return [=]{ return k; }(); }(); // ok
+ int d = []{ return [=]{ return n; }(); }(); // expected-error {{'this' cannot be implicitly captured in this context}}
+ };
+}
+
+namespace PR18473 {
+ template<typename T> void f() {
+ T t(0);
+ (void) [=]{ int n = t; }; // expected-error {{deleted}}
+ }
+
+ template void f<int>();
+ struct NoCopy {
+ NoCopy(int);
+ NoCopy(const NoCopy &) = delete; // expected-note {{deleted}}
+ operator int() const;
+ };
+ template void f<NoCopy>(); // expected-note {{instantiation}}
+}
+
+void PR19249() {
+ auto x = [&x]{}; // expected-error {{cannot appear in its own init}}
+}
diff --git a/test/SemaCXX/linkage.cpp b/test/SemaCXX/linkage.cpp
index 13d295a..8a2013f 100644
--- a/test/SemaCXX/linkage.cpp
+++ b/test/SemaCXX/linkage.cpp
@@ -5,6 +5,8 @@
// RUN: %clang_cc1 -Werror -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
+// CHECK: @_ZZN5test61A3fooEvE3bar = linkonce_odr global i32 0, align 4
+
// PR8926
namespace test0 {
typedef struct {
@@ -103,3 +105,20 @@
};
}
}
+
+// Test that we don't compute linkage too hastily before we're done
+// processing a record decl. rdar://15928125
+namespace test6 {
+ typedef struct {
+ int foo() {
+ // Tested at top of file.
+ static int bar = 0;
+ return bar++;
+ }
+ } A;
+
+ void test() {
+ A a;
+ a.foo();
+ }
+}
diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp
index 075f5e7..a7eb15f 100644
--- a/test/SemaCXX/linkage2.cpp
+++ b/test/SemaCXX/linkage2.cpp
@@ -213,3 +213,7 @@
void pr16247_bar(int) {}
void pr16247_bar(double) {}
}
+namespace PR18964 {
+ unsigned &*foo; //expected-error{{'foo' declared as a pointer to a reference of type}}
+ extern struct {} *foo; // don't assert
+}
diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp
index 239aecf..e0955ae 100644
--- a/test/SemaCXX/member-expr.cpp
+++ b/test/SemaCXX/member-expr.cpp
@@ -193,7 +193,7 @@
};
template <class T> void call_func(T t) {
- t->func(); // expected-error-re 2 {{member reference type 'PR15045::bar' is not a pointer$}} \
+ t->func(); // expected-error-re 2 {{member reference type 'PR15045::bar' is not a pointer{{$}}}} \
// expected-note {{did you mean to use '.' instead?}}
}
@@ -207,7 +207,7 @@
// Make sure a fixit isn't given in the case that the '->' isn't actually
// the problem (the problem is with the return value of an operator->).
- f->func(); // expected-error-re {{member reference type 'PR15045::bar' is not a pointer$}}
+ f->func(); // expected-error-re {{member reference type 'PR15045::bar' is not a pointer{{$}}}}
call_func(e); // expected-note {{in instantiation of function template specialization 'PR15045::call_func<PR15045::bar>' requested here}}
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index 6e4fd5d..d8a00b3 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -100,3 +100,13 @@
};
void f(Sprite& x) { x = x; }
}
+
+namespace PR18560 {
+ struct X { int m; };
+
+ template<typename T = X,
+ typename U = decltype(T::m)>
+ int f();
+
+ struct Y { int b = f(); };
+}
diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp
index aee8e2e..e7c4ae9 100644
--- a/test/SemaCXX/member-pointer-ms.cpp
+++ b/test/SemaCXX/member-pointer-ms.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify %s
-// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify -DVMB %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMB %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMV -fms-memptr-rep=virtual %s
//
// This file should also give no diagnostics when run through cl.exe from MSVS
// 2012, which supports C++11 and static_assert. It should pass for both 64-bit
@@ -18,22 +19,73 @@
int f;
};
+#ifdef VMB
enum {
+ kSingleDataAlign = 1 * sizeof(int),
+ kSingleFunctionAlign = 1 * sizeof(void *),
+ kMultipleDataAlign = 1 * sizeof(int),
+ // Everything with more than 1 field is 8 byte aligned, except virtual data
+ // member pointers on x64 (ugh).
+ kMultipleFunctionAlign = 8,
+#ifdef _M_X64
+ kVirtualDataAlign = 4,
+#else
+ kVirtualDataAlign = 8,
+#endif
+ kVirtualFunctionAlign = 8,
+ kUnspecifiedDataAlign = 8,
+ kUnspecifiedFunctionAlign = 8,
+
kSingleDataSize = 1 * sizeof(int),
kSingleFunctionSize = 1 * sizeof(void *),
kMultipleDataSize = 1 * sizeof(int),
kMultipleFunctionSize = 2 * sizeof(void *),
kVirtualDataSize = 2 * sizeof(int),
kVirtualFunctionSize = 2 * sizeof(int) + 1 * sizeof(void *),
- // Unspecified is weird, it's 1 more slot than virtual.
- kUnspecifiedDataSize = kVirtualDataSize + 1 * sizeof(int),
- kUnspecifiedFunctionSize = kVirtualFunctionSize + 1 * sizeof(void *),
+ kUnspecifiedDataSize = 3 * sizeof(int),
+ kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
};
+#elif VMV
+enum {
+ // Everything with more than 1 field is 8 byte aligned, except virtual data
+ // member pointers on x64 (ugh).
+#ifdef _M_X64
+ kVirtualDataAlign = 4,
+#else
+ kVirtualDataAlign = 8,
+#endif
+ kMultipleDataAlign = kVirtualDataAlign,
+ kSingleDataAlign = kVirtualDataAlign,
+
+ kUnspecifiedFunctionAlign = 8,
+ kVirtualFunctionAlign = kUnspecifiedFunctionAlign,
+ kMultipleFunctionAlign = kUnspecifiedFunctionAlign,
+ kSingleFunctionAlign = kUnspecifiedFunctionAlign,
+
+ kUnspecifiedDataSize = 3 * sizeof(int),
+ kVirtualDataSize = kUnspecifiedDataSize,
+ kMultipleDataSize = kUnspecifiedDataSize,
+ kSingleDataSize = kUnspecifiedDataSize,
+
+ kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
+ kVirtualFunctionSize = kUnspecifiedFunctionSize,
+ kMultipleFunctionSize = kUnspecifiedFunctionSize,
+ kSingleFunctionSize = kUnspecifiedFunctionSize,
+};
+#else
+#error "test doesn't yet support this mode!"
+#endif
// incomplete types
+#ifdef VMB
class __single_inheritance IncSingle;
class __multiple_inheritance IncMultiple;
class __virtual_inheritance IncVirtual;
+#else
+class IncSingle;
+class IncMultiple;
+class IncVirtual;
+#endif
static_assert(sizeof(int IncSingle::*) == kSingleDataSize, "");
static_assert(sizeof(int IncMultiple::*) == kMultipleDataSize, "");
static_assert(sizeof(int IncVirtual::*) == kVirtualDataSize, "");
@@ -41,6 +93,13 @@
static_assert(sizeof(void (IncMultiple::*)()) == kMultipleFunctionSize, "");
static_assert(sizeof(void (IncVirtual::*)()) == kVirtualFunctionSize, "");
+static_assert(__alignof(int IncSingle::*) == kSingleDataAlign, "");
+static_assert(__alignof(int IncMultiple::*) == kMultipleDataAlign, "");
+static_assert(__alignof(int IncVirtual::*) == kVirtualDataAlign, "");
+static_assert(__alignof(void (IncSingle::*)()) == kSingleFunctionAlign, "");
+static_assert(__alignof(void (IncMultiple::*)()) == kMultipleFunctionAlign, "");
+static_assert(__alignof(void (IncVirtual::*)()) == kVirtualFunctionAlign, "");
+
// An incomplete type with an unspecified inheritance model seems to take one
// more slot than virtual. It's not clear what it's used for yet.
class IncUnspecified;
@@ -62,9 +121,15 @@
// Test both declared and defined templates.
template <typename T> class X;
+#ifdef VMB
template <> class __single_inheritance X<IncSingle>;
template <> class __multiple_inheritance X<IncMultiple>;
template <> class __virtual_inheritance X<IncVirtual>;
+#else
+template <> class X<IncSingle>;
+template <> class X<IncMultiple>;
+template <> class X<IncVirtual>;
+#endif
// Don't declare X<IncUnspecified>.
static_assert(sizeof(int X<IncSingle>::*) == kSingleDataSize, "");
static_assert(sizeof(int X<IncMultiple>::*) == kMultipleDataSize, "");
@@ -117,9 +182,7 @@
static_assert(sizeof(variable_forces_sizing) == kUnspecifiedDataSize, "");
static_assert(sizeof(MemPtr1) == kUnspecifiedDataSize, "");
-// FIXME: Clang fails this assert because it locks in the inheritance model at
-// the point of the typedef instead of the first usage, while MSVC does not.
-//static_assert(sizeof(MemPtr2) == kSingleDataSize, "");
+static_assert(sizeof(MemPtr2) == kSingleDataSize, "");
struct MemPtrInBody {
typedef int MemPtrInBody::*MemPtr;
@@ -164,5 +227,48 @@
void (T::*func_ptr)();
};
+#ifdef VMB
int Virtual::*CastTest = reinterpret_cast<int Virtual::*>(&AA::x);
// expected-error@-1 {{cannot reinterpret_cast from member pointer type}}
+#endif
+
+namespace ErrorTest {
+template <typename T, typename U> struct __single_inheritance A;
+ // expected-warning@-1 {{inheritance model ignored on primary template}}
+template <typename T> struct __multiple_inheritance A<T, T>;
+ // expected-warning@-1 {{inheritance model ignored on partial specialization}}
+template <> struct __single_inheritance A<int, float>;
+
+struct B {}; // expected-note {{B defined here}}
+struct __multiple_inheritance B; // expected-error{{inheritance model does not match definition}}
+
+struct __multiple_inheritance C {}; // expected-error{{inheritance model does not match definition}}
+ // expected-note@-1 {{C defined here}}
+
+struct __virtual_inheritance D;
+struct D : virtual B {};
+}
+#ifdef VMB
+#pragma pointers_to_members(full_generality, multiple_inheritance)
+struct TrulySingleInheritance;
+static_assert(sizeof(int TrulySingleInheritance::*) == kMultipleDataSize, "");
+#pragma pointers_to_members(best_case)
+// This definition shouldn't conflict with the increased generality that the
+// multiple_inheritance model gave to TrulySingleInheritance.
+struct TrulySingleInheritance {};
+
+// Even if a definition proceeds the first mention of a pointer to member, we
+// still give the record the fully general representation.
+#pragma pointers_to_members(full_generality, virtual_inheritance)
+struct SingleInheritanceAsVirtualAfterPragma {};
+static_assert(sizeof(int SingleInheritanceAsVirtualAfterPragma::*) == 12, "");
+
+#pragma pointers_to_members(best_case)
+
+// The above holds even if the pragma comes after the definition.
+struct SingleInheritanceAsVirtualBeforePragma {};
+#pragma pointers_to_members(virtual_inheritance)
+static_assert(sizeof(int SingleInheritanceAsVirtualBeforePragma::*) == 12, "");
+
+#pragma pointers_to_members(single) // expected-error{{unexpected 'single'}}
+#endif
diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp
index 4e8b4a8..b8631bc 100644
--- a/test/SemaCXX/member-pointer.cpp
+++ b/test/SemaCXX/member-pointer.cpp
@@ -7,12 +7,13 @@
struct E : A {};
struct F : D, E {};
struct G : virtual D {};
+class H : A {}; // expected-note 2{{implicitly declared private here}}
int A::*pdi1;
int (::A::*pdi2);
int (A::*pfi)(int);
-int B::*pbi; // expected-error {{expected a class or namespace}}
+int B::*pbi; // expected-error {{'B' is not a class, namespace, or scoped enumeration}}
int C::*pci; // expected-error {{'pci' does not point into a class}}
void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}
int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}}
@@ -115,8 +116,11 @@
(void)(d.*pai);
(void)(pd->*pai);
F f, *ptrf = &f;
- (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'F'}}
- (void)(ptrf->*pai); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'F *'}}
+ (void)(f.*pai); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A'}}
+ (void)(ptrf->*pai); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A'}}
+ H h, *ptrh = &h;
+ (void)(h.*pai); // expected-error {{cannot cast 'H' to its private base class 'A'}}
+ (void)(ptrh->*pai); // expected-error {{cannot cast 'H' to its private base class 'A'}}
(void)(hm.*i); // expected-error {{pointer-to-member}}
(void)(phm->*i); // expected-error {{pointer-to-member}}
diff --git a/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp b/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp
new file mode 100644
index 0000000..5a399aa
--- /dev/null
+++ b/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -verify %s
+
+struct S {
+ virtual ~S() = delete; // expected-note {{'~S' has been explicitly marked deleted here}}
+ void operator delete(void*, int);
+ void operator delete(void*, double);
+} s; // expected-error {{attempt to use a deleted function}}
+
+struct T { // expected-note{{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+ virtual ~T() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}}
+ void operator delete(void*, int);
+ void operator delete(void*, double);
+} t; // expected-error {{attempt to use a deleted function}}
diff --git a/test/SemaCXX/microsoft-dtor-lookup.cpp b/test/SemaCXX/microsoft-dtor-lookup.cpp
index d264bab..51129ae 100644
--- a/test/SemaCXX/microsoft-dtor-lookup.cpp
+++ b/test/SemaCXX/microsoft-dtor-lookup.cpp
@@ -1,12 +1,11 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi itanium -fsyntax-only %s
-// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -verify -DMSVC_ABI %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only %s
+// RUN: %clang_cc1 -triple %ms_abi_triple -verify %s
namespace Test1 {
// Should be accepted under the Itanium ABI (first RUN line) but rejected
// under the Microsoft ABI (second RUN line), as Microsoft ABI requires
-// operator delete() lookups to be done at all virtual destructor declaration
-// points.
+// operator delete() lookups to be done when vtables are marked used.
struct A {
void operator delete(void *); // expected-note {{member found by ambiguous name lookup}}
@@ -24,6 +23,10 @@
virtual ~VC(); // expected-error {{member 'operator delete' found in multiple base classes of different types}}
};
+void f(VC vc) {
+ // This marks VC's vtable used.
+}
+
}
namespace Test2 {
@@ -32,10 +35,9 @@
// requires a dtor for B, but we can't implicitly define it because ~A is
// private. bar should be able to call A's private dtor without error, even
// though MSVC rejects bar.
-
class A {
private:
- ~A(); // expected-note 2{{declared private here}}
+ ~A(); // expected-note {{declared private here}}
int a;
};
@@ -54,7 +56,7 @@
};
void foo(B b) { } // expected-note {{implicit destructor for 'Test2::B' first required here}}
-void bar(A a) { } // expected-error {{variable of type 'Test2::A' has private destructor}}
+void bar(A a) { } // no error; MSVC rejects this, but we skip the direct access check.
void baz(D d) { } // no error
}
@@ -64,13 +66,13 @@
class A {
A();
- ~A(); // expected-note 2{{implicitly declared private here}}
+ ~A(); // expected-note {{implicitly declared private here}}
friend void bar(A);
int a;
};
void bar(A a) { }
-void baz(A a) { } // expected-error {{variable of type 'Test3::A' has private destructor}}
+void baz(A a) { } // no error; MSVC rejects this, but the standard allows it.
// MSVC accepts foo() but we reject it for consistency with Itanium. MSVC also
// rejects this if A has a copy ctor or if we call A's ctor.
diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp
index 619bc61..96bed07 100644
--- a/test/SemaCXX/missing-members.cpp
+++ b/test/SemaCXX/missing-members.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
namespace A {
namespace B {
- class C { }; // expected-note 2 {{'A::B::C' declared here}}
+ class C { }; // expected-note {{'A::B::C' declared here}}
struct S { };
union U { };
}
@@ -18,13 +18,12 @@
}
void g() {
- A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}}
+ A::B::D::E; // expected-error-re {{no member named 'D' in namespace 'A::B'{{$}}}}
// FIXME: The typo corrections below should be suppressed since A::B::C
// doesn't have a member named D.
B::B::C::D; // expected-error {{no member named 'C' in 'B::B'; did you mean 'A::B::C'?}} \
- // expected-error {{no member named 'D' in 'A::B::C'}}
- ::C::D; // expected-error {{no member named 'C' in the global namespace; did you mean 'A::B::C'?}}\
- // expected-error {{no member named 'D' in 'A::B::C'}}
+ // expected-error-re {{no member named 'D' in 'A::B::C'{{$}}}}
+ ::C::D; // expected-error-re {{no member named 'C' in the global namespace{{$}}}}
}
int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}}
diff --git a/test/SemaCXX/ms-interface.cpp b/test/SemaCXX/ms-interface.cpp
index 3625f70..e7386ce 100644
--- a/test/SemaCXX/ms-interface.cpp
+++ b/test/SemaCXX/ms-interface.cpp
@@ -10,7 +10,7 @@
bool operator!();
// expected-error@+1 {{operator 'operator int' is not permitted within an interface type}}
operator int();
- // expected-error@+1 {{nested class I1::<anonymous> is not permitted within an interface type}}
+ // expected-error@+1 {{nested class I1::(anonymous) is not permitted within an interface type}}
struct { int a; };
void fn2() {
struct A { }; // should be ignored: not a nested class
diff --git a/test/SemaCXX/ms_struct.cpp b/test/SemaCXX/ms_struct.cpp
index 37fa9a7..2832b56 100644
--- a/test/SemaCXX/ms_struct.cpp
+++ b/test/SemaCXX/ms_struct.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-apple-darwin9 -std=c++11 %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -Wno-error=incompatible-ms-struct -verify -triple i686-apple-darwin9 -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-error=incompatible-ms-struct -verify -triple armv7-apple-darwin9 -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -DTEST_FOR_ERROR -verify -triple armv7-apple-darwin9 -std=c++11 %s
#pragma ms_struct on
@@ -9,10 +10,29 @@
};
struct B : public A {
+#ifdef TEST_FOR_ERROR
+ // expected-error@-2 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#else
+ // expected-warning@-4 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#endif
unsigned long c:16;
int d;
B();
};
static_assert(__builtin_offsetof(B, d) == 12,
- "We can't allocate the bitfield into the padding under ms_struct");
\ No newline at end of file
+ "We can't allocate the bitfield into the padding under ms_struct");
+
+// rdar://16178895
+struct C {
+#ifdef TEST_FOR_ERROR
+ // expected-error@-2 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#else
+ // expected-warning@-4 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#endif
+ virtual void foo();
+ long long n;
+};
+
+static_assert(__builtin_offsetof(C, n) == 8,
+ "long long field in ms_struct should be 8-byte aligned");
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index df4f1b2..8587e70 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -85,10 +85,13 @@
void f3() {
N::x = 0; // expected-error {{use of undeclared identifier 'N'}}
- int N;
- N::x = 0; // expected-error {{expected a class or namespace}}
+ // FIXME: Consider including the kind of entity that 'N' is ("variable 'N'
+ // declared here", "template 'X' declared here", etc) to help explain what it
+ // is if it's 'not a class, namespace, or scoped enumeration'.
+ int N; // expected-note {{'N' declared here}}
+ N::x = 0; // expected-error {{'N' is not a class, namespace, or scoped enumeration}}
{ int A; A::ax = 0; }
- { typedef int A; A::ax = 0; } // expected-error{{expected a class or namespace}}
+ { typedef int A; A::ax = 0; } // expected-error{{'A' (aka 'int') is not a class, namespace, or scoped enumeration}}
{ typedef A::C A; A::ax = 0; } // expected-error {{no member named 'ax'}}
{ typedef A::C A; A::cx = 0; }
}
@@ -114,7 +117,7 @@
};
void f() {
- return E::X; // expected-error{{expected a class or namespace}}
+ return E::X; // expected-error{{'E::Nested::E' is not a class, namespace, or scoped enumeration}}
}
}
}
@@ -143,7 +146,7 @@
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-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'$}}
+void A::f() {} // expected-error-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'{{$}}}}
void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does not match any declaration in namespace 'A'}}
@@ -160,7 +163,7 @@
void f();
// FIXME: if we move this to a separate definition of N, things break!
}
-void ::global_func2(int) { } // expected-error{{extra qualification on member 'global_func2'}}
+void ::global_func2(int) { } // expected-warning{{extra qualification on member 'global_func2'}}
void N::f() { } // okay
@@ -308,4 +311,4 @@
}
namespace TypedefNamespace { typedef int F; };
-TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{expected a class or namespace}}
+TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{'F' (aka 'int') is not a class, namespace, or scoped enumeration}}
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index 7facd10..175ebe7 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu -Wno-new-returns-null
#include <stddef.h>
@@ -517,3 +517,7 @@
return 0;
}
};
+
+namespace PR18544 {
+ inline void *operator new(size_t); // expected-error {{'operator new' cannot be declared inside a namespace}}
+}
diff --git a/test/SemaCXX/new-null.cpp b/test/SemaCXX/new-null.cpp
new file mode 100644
index 0000000..b2be0c5
--- /dev/null
+++ b/test/SemaCXX/new-null.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+typedef __SIZE_TYPE__ size_t;
+
+#if __cplusplus >= 201103L
+struct S1 {
+ void *operator new(size_t n) {
+ return nullptr; // expected-warning {{'operator new' should not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
+ }
+ void *operator new[](size_t n) noexcept {
+ return __null;
+ }
+};
+#endif
+
+struct S2 {
+ static size_t x;
+ void *operator new(size_t n) throw() {
+ return 0;
+ }
+ void *operator new[](size_t n) {
+ return (void*)0;
+#if __cplusplus >= 201103L
+ // expected-warning@-2 {{'operator new[]' should not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
+#else
+ // expected-warning-re@-4 {{'operator new[]' should not return a null pointer unless it is declared 'throw()'{{$}}}}
+#endif
+ }
+};
+
+struct S3 {
+ void *operator new(size_t n) {
+ return 1-1;
+#if __cplusplus >= 201103L
+ // expected-error@-2 {{cannot initialize return object of type 'void *' with an rvalue of type 'int'}}
+#else
+ // expected-warning@-4 {{expression which evaluates to zero treated as a null pointer constant of type 'void *'}}
+ // expected-warning@-5 {{'operator new' should not return a null pointer unless it is declared 'throw()'}}
+#endif
+ }
+ void *operator new[](size_t n) {
+ return (void*)(1-1); // expected-warning {{'operator new[]' should not return a null pointer unless it is declared 'throw()'}}
+ }
+};
+
+#if __cplusplus >= 201103L
+template<bool B> struct S4 {
+ void *operator new(size_t n) noexcept(B) {
+ return 0; // expected-warning {{'operator new' should not return a null pointer}}
+ }
+};
+template struct S4<true>;
+template struct S4<false>; // expected-note {{in instantiation of}}
+#endif
+
+template<typename ...T> struct S5 { // expected-warning 0-1{{extension}}
+ void *operator new(size_t n) throw(T...) {
+ return 0; // expected-warning {{'operator new' should not return a null pointer}}
+ }
+};
+template struct S5<>;
+template struct S5<int>; // expected-note {{in instantiation of}}
diff --git a/test/SemaCXX/nonnull.cpp b/test/SemaCXX/nonnull.cpp
new file mode 100644
index 0000000..9ff6d11
--- /dev/null
+++ b/test/SemaCXX/nonnull.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int I>
+struct TS {
+ __attribute__((returns_nonnull))
+ void *value_dependent(void) {
+ return I; // no-warning
+ }
+
+ __attribute__((returns_nonnull))
+ void *value_independent(void) {
+ return 0; // expected-warning {{null returned from function that requires a non-null return value}}
+ }
+};
+
diff --git a/test/SemaCXX/null_in_arithmetic_ops.cpp b/test/SemaCXX/null_in_arithmetic_ops.cpp
index a919213..3b42ab4 100644
--- a/test/SemaCXX/null_in_arithmetic_ops.cpp
+++ b/test/SemaCXX/null_in_arithmetic_ops.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -fblocks -Wnull-arithmetic -verify -Wno-string-plus-int %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -fblocks -Wnull-arithmetic -verify -Wno-string-plus-int -Wno-tautological-pointer-compare %s
#include <stddef.h>
void f() {
diff --git a/test/SemaCXX/nullptr_in_arithmetic_ops.cpp b/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
index 9671353..60b4670 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++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-pointer-compare -fblocks -std=c++11 -verify %s
void foo() {
int a;
diff --git a/test/SemaCXX/old-style-cast.cpp b/test/SemaCXX/old-style-cast.cpp
new file mode 100644
index 0000000..73a78e4
--- /dev/null
+++ b/test/SemaCXX/old-style-cast.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify -Wold-style-cast %s
+
+void test1() {
+ long x = (long)12; // expected-warning {{use of old-style cast}}
+ (long)x; // expected-warning {{use of old-style cast}} expected-warning {{expression result unused}}
+ (void**)x; // expected-warning {{use of old-style cast}} expected-warning {{expression result unused}}
+ long y = static_cast<long>(12);
+ (void)y;
+ typedef void VOID;
+ (VOID)y;
+}
diff --git a/test/SemaCXX/operator-arrow-depth.cpp b/test/SemaCXX/operator-arrow-depth.cpp
index 3e2ba8e..769dae0 100644
--- a/test/SemaCXX/operator-arrow-depth.cpp
+++ b/test/SemaCXX/operator-arrow-depth.cpp
@@ -9,7 +9,7 @@
template<int N> struct B {
A<N-1> operator->(); // expected-note +{{'operator->' declared here produces an object of type 'A<}}
#if MAX != 2
- // expected-note-re@-2 {{(skipping (120|2) 'operator->'s in backtrace)}}
+ // expected-note-re@-2 {{(skipping {{120|2}} 'operator->'s in backtrace)}}
#endif
};
@@ -22,5 +22,5 @@
int n = good->n;
B<MAX/2 + 1> bad;
-int m = bad->n; // expected-error-re {{use of 'operator->' on type 'B<(2|10|128) / 2 \+ 1>' would invoke a sequence of more than (2|10|128) 'operator->' calls}}
+int m = bad->n; // expected-error-re {{use of 'operator->' on type 'B<{{2|10|128}} / 2 + 1>' would invoke a sequence of more than {{2|10|128}} 'operator->' calls}}
// expected-note@-1 {{use -foperator-arrow-depth=N to increase 'operator->' limit}}
diff --git a/test/SemaCXX/overload-0x.cpp b/test/SemaCXX/overload-0x.cpp
index 677d16a..1c185a5 100644
--- a/test/SemaCXX/overload-0x.cpp
+++ b/test/SemaCXX/overload-0x.cpp
@@ -1,7 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -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}}
+ 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}}
+#if __cplusplus >= 201103L
+ // expected-note@-2 {{candidate function (the implicit move assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
+#endif
A &operator=(void*); // expected-note {{candidate function not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
};
@@ -9,3 +13,79 @@
a = "help"; // expected-error {{no viable overloaded '='}}
}
}
+
+namespace PR16314 {
+ void f(char*);
+ int &f(...);
+ void x()
+ {
+ int &n = f("foo");
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+ // expected-error@-3 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'void'}}
+#endif
+ }
+}
+
+namespace warn_if_best {
+ int f(char *);
+ void f(double);
+ void x()
+ {
+ int n = f("foo");
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#else
+ // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
+#endif
+ }
+}
+
+namespace userdefined_vs_illformed {
+ struct X { X(const char *); };
+
+ void *f(char *p); // best for C++03
+ double f(X x); // best for C++11
+ void g()
+ {
+ double d = f("foo");
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+ // expected-error@-3 {{cannot initialize a variable of type 'double' with an rvalue of type 'void *'}}
+#endif
+ }
+}
+
+namespace sfinae_test {
+ int f(int, char*);
+
+ template<int T>
+ struct S { typedef int type; };
+
+ template<>
+ struct S<sizeof(int)> { typedef void type; };
+
+ // C++11: SFINAE failure
+ // C++03: ok
+ template<typename T> int cxx11_ignored(T, typename S<sizeof(f(T(), "foo"))>::type *);
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#else
+ // expected-note@-4 {{candidate template ignored: substitution failure}}
+#endif
+
+ // C++11: better than latter
+ // C++03: worse than latter
+ template<typename T> void g(T, ...);
+ template<typename T> int g(T, typename S<sizeof(f(T(), "foo"))>::type *);
+#if __cplusplus < 201103L
+ // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#endif
+
+ int a = cxx11_ignored(0, 0);
+ int b = g(0, 0);
+#if __cplusplus >= 201103L
+ // expected-error@-3 {{no matching function for call to 'cxx11_ignored'}}
+ // expected-error@-3 {{cannot initialize a variable of type 'int' with an rvalue of type 'void'}}
+#endif
+}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 99105cb..cd2b2d3 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -452,3 +452,58 @@
Result = 1; // expected-error {{no viable overloaded '='}} // expected-note {{type 'PointerUnion<int *, float *>' is incomplete}}
}
}
+
+namespace PR14995 {
+ struct B {};
+ template<typename ...T> void operator++(B, T...) {}
+
+ void f() {
+ B b;
+ b++; // ok
+ ++b; // ok
+ }
+
+ template<typename... T>
+ struct C {
+ void operator-- (T...) {}
+ };
+
+ void g() {
+ C<int> postfix;
+ C<> prefix;
+ postfix--; // ok
+ --prefix; // ok
+ }
+
+ struct D {};
+ template<typename T> void operator++(D, T) {}
+
+ void h() {
+ D d;
+ d++; // ok
+ ++d; // expected-error{{cannot increment value of type 'PR14995::D'}}
+ }
+
+ template<typename...T> struct E {
+ void operator++(T...) {} // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
+ };
+
+ E<char> e; // expected-note {{in instantiation of template class 'PR14995::E<char>' requested here}}
+
+ struct F {
+ template<typename... T>
+ int operator++ (T...) {}
+ };
+
+ int k1 = F().operator++(0, 0);
+ int k2 = F().operator++('0');
+ // expected-error@-5 {{overloaded 'operator++' must be a unary or binary operator}}
+ // expected-note@-3 {{in instantiation of function template specialization 'PR14995::F::operator++<int, int>' requested here}}
+ // expected-error@-4 {{no matching member function for call to 'operator++'}}
+ // expected-note@-8 {{candidate template ignored: substitution failure}}
+ // expected-error@-9 {{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
+ // expected-note@-6 {{in instantiation of function template specialization 'PR14995::F::operator++<char>' requested here}}
+ // expected-error@-7 {{no matching member function for call to 'operator++'}}
+ // expected-note@-12 {{candidate template ignored: substitution failure}}
+} // namespace PR14995
+
diff --git a/test/SemaCXX/pr13394-crash-on-invalid.cpp b/test/SemaCXX/pr13394-crash-on-invalid.cpp
index 841e3c2..304ee92 100644
--- a/test/SemaCXX/pr13394-crash-on-invalid.cpp
+++ b/test/SemaCXX/pr13394-crash-on-invalid.cpp
@@ -8,12 +8,12 @@
}
namespace gatekeeper_v1 {
namespace gatekeeper_factory_v1 {
- struct closure_t { // expected-note {{'closure_t' declared here}}
+ struct closure_t { // expected-note {{'closure_t' declared here}} expected-note {{'gatekeeper_factory_v1::closure_t' declared here}}
gatekeeper_v1::closure_t* create(); // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean simply 'closure_t'?}}
};
}
// FIXME: Typo correction should remove the 'gatekeeper_v1::' name specifier
- gatekeeper_v1::closure_t *x; // expected-error-re {{no type named 'closure_t' in namespace 'gatekeeper_v1'$}}
+ gatekeeper_v1::closure_t *x; // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean 'gatekeeper_factory_v1::closure_t'}}
}
namespace Foo {
diff --git a/test/SemaCXX/pr18284-crash-on-invalid.cpp b/test/SemaCXX/pr18284-crash-on-invalid.cpp
new file mode 100644
index 0000000..5b1cb21
--- /dev/null
+++ b/test/SemaCXX/pr18284-crash-on-invalid.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// Don't crash (PR18284).
+
+namespace n1 {
+class A { };
+class C { A a; };
+
+A::RunTest() {} // expected-error {{C++ requires a type specifier for all declarations}}
+
+void f() {
+ new C;
+}
+} // namespace n1
+
+namespace n2 {
+class A { };
+class C : public A { };
+
+A::RunTest() {} // expected-error {{C++ requires a type specifier for all declarations}}
+
+void f() {
+ new C;
+}
+} // namespace n2
diff --git a/test/SemaCXX/pr9812.c b/test/SemaCXX/pr9812.c
new file mode 100644
index 0000000..cbbe44b
--- /dev/null
+++ b/test/SemaCXX/pr9812.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#define bool _Bool
+int test1(int argc, char** argv)
+{
+ bool signed; // expected-error {{'bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+
+ return 0;
+}
+#undef bool
+
+typedef int bool;
+
+int test2(int argc, char** argv)
+{
+ bool signed; // expected-error {{'type-name' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+ _Bool signed; // expected-error {{'_Bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+
+ return 0;
+}
+
diff --git a/test/SemaCXX/pr9812.cpp b/test/SemaCXX/pr9812.cpp
new file mode 100644
index 0000000..2cd0bed
--- /dev/null
+++ b/test/SemaCXX/pr9812.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int test(int, char**)
+{
+ bool signed; // expected-error {{'bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+
+ return 0;
+}
+
diff --git a/test/SemaCXX/pragma-vtordisp.cpp b/test/SemaCXX/pragma-vtordisp.cpp
new file mode 100644
index 0000000..49841c5
--- /dev/null
+++ b/test/SemaCXX/pragma-vtordisp.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify %s
+
+struct A { int a; };
+
+#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}
+#pragma vtordisp(push, 0)
+#pragma vtordisp(push, 1)
+#pragma vtordisp(push, 2)
+struct B : virtual A { int b; };
+#pragma vtordisp(pop)
+#pragma vtordisp(pop)
+#pragma vtordisp(pop)
+#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}
+
+#pragma vtordisp(push, 3) // expected-warning {{expected integer between 0 and 2 inclusive in '#pragma vtordisp' - ignored}}
+#pragma vtordisp()
+
+#define ONE 1
+#pragma vtordisp(push, ONE)
+#define TWO 1
+#pragma vtordisp(push, TWO)
+
+// Test a reset.
+#pragma vtordisp()
+#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}
+
+#pragma vtordisp( // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}
+#pragma vtordisp(asdf) // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}
+#pragma vtordisp(,) // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}
+#pragma vtordisp // expected-warning {{missing '(' after '#pragma vtordisp' - ignoring}}
+#pragma vtordisp(3) // expected-warning {{expected integer between 0 and 2 inclusive in '#pragma vtordisp' - ignored}}
+#pragma vtordisp(), stuff // expected-warning {{extra tokens}}
+
+struct C {
+// FIXME: Our implementation based on token insertion makes it impossible for
+// the pragma to appear everywhere we should support it.
+//#pragma vtordisp()
+ struct D : virtual A {
+ };
+};
diff --git a/test/SemaCXX/pragma-weak.cpp b/test/SemaCXX/pragma-weak.cpp
index 057cf6b..c1ff206 100644
--- a/test/SemaCXX/pragma-weak.cpp
+++ b/test/SemaCXX/pragma-weak.cpp
@@ -6,3 +6,6 @@
void foo() {
};
}
+
+extern "C" int Test;
+#pragma weak test = Test
diff --git a/test/SemaCXX/primary-base.cpp b/test/SemaCXX/primary-base.cpp
index 0b6aaef..d305aa3 100644
--- a/test/SemaCXX/primary-base.cpp
+++ b/test/SemaCXX/primary-base.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
// expected-no-diagnostics
class A { virtual void f(); };
class B : virtual A { };
diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp
index 23164fa..8eef6f4 100644
--- a/test/SemaCXX/qualified-id-lookup.cpp
+++ b/test/SemaCXX/qualified-id-lookup.cpp
@@ -94,7 +94,7 @@
void test_a() {
a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'; did you mean 'a::a::a::i'?}}
a::a::a::i = 4;
- a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'$}}
+ a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'{{$}}}}
}
struct Undef { // expected-note{{definition of 'Undef' is not complete until the closing '}'}}
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index 37fc2a8..cfe7dc1 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -85,9 +85,19 @@
typedef int& intref;
typedef intref& intrefref; // C++ DR 106: reference collapsing
- typedef intref const intref_c; // okay. FIXME: how do we verify that this is the same type as intref?
+ typedef intref const intref_c; // expected-warning {{'const' qualifier on reference type 'intref' (aka 'int &') has no effect}}
+ typedef intref_c intref; // ok, same type
+
+ typedef intref volatile intref; // expected-warning {{'volatile' qualifier on reference type 'intref' (aka 'int &') has no effect}}
+ typedef intref _Atomic intref; // expected-warning {{'_Atomic' qualifier on reference type 'intref' (aka 'int &') has no effect}}
+
+ void restrict_ref(__restrict intref); // ok
+ void restrict_ref(int &__restrict); // ok
}
+template<typename T> int const_param(const T) {}
+int const_ref_param = const_param<int&>(const_ref_param); // no-warning
+
class string {
char *Data;
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
index a4bc432..4284032 100644
--- a/test/SemaCXX/reinterpret-cast.cpp
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -96,12 +96,12 @@
void (structure::*psf)() = 0;
(void)reinterpret_cast<int (structure::*)()>(psf);
- (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
- (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
+ (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error-re {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
+ (void)reinterpret_cast<int structure::*>(psf); // expected-error-re {{reinterpret_cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'int structure::*' is not allowed}}
// Cannot cast from integers to member pointers, not even the null pointer
// literal.
- (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (structure::*)()' is not allowed}}
+ (void)reinterpret_cast<void (structure::*)()>(0); // expected-error-re {{reinterpret_cast from 'int' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
(void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}}
}
diff --git a/test/SemaCXX/return-noreturn.cpp b/test/SemaCXX/return-noreturn.cpp
index 617de00..16bb86c 100644
--- a/test/SemaCXX/return-noreturn.cpp
+++ b/test/SemaCXX/return-noreturn.cpp
@@ -40,6 +40,14 @@
switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); }
}
+ // FIXME: detect noreturn destructors triggered by calls to delete.
+ int f7(int x) {
+ switch (x) default: L1: L2: case 4: {
+ pr6884_abort_struct *p = new pr6884_abort_struct();
+ delete p;
+ }
+ } // 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) {
diff --git a/test/SemaCXX/return-stack-addr.cpp b/test/SemaCXX/return-stack-addr.cpp
index fbbaf83..7670798e 100644
--- a/test/SemaCXX/return-stack-addr.cpp
+++ b/test/SemaCXX/return-stack-addr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
int* ret_local() {
int x = 1;
@@ -108,6 +108,11 @@
return const_cast<int*>(&x); // expected-warning {{address of stack memory}}
}
+struct A { virtual ~A(); }; struct B : A {};
+A* ret_cpp_dynamic_cast(B b) {
+ return dynamic_cast<A*>(&b); // expected-warning {{address of stack memory}}
+}
+
// PR 7999 - handle the case where a field is itself a reference.
template <typename T> struct PR7999 {
PR7999(T& t) : value(t) {}
@@ -137,5 +142,17 @@
}
}
-// TODO: test case for dynamic_cast. clang does not yet have
-// support for C++ classes to write such a test case.
+// Don't warn about returning a local variable from a surrounding function if
+// we're within a lambda-expression.
+void ret_from_lambda() {
+ int a;
+ int &b = a;
+ (void) [&]() -> int& { return a; };
+ (void) [&]() -> int& { return b; };
+ (void) [=]() mutable -> int& { return a; };
+ (void) [=]() mutable -> int& { return b; };
+ (void) [&]() -> int& { int a; return a; }; // expected-warning {{reference to stack}}
+ (void) [=]() -> int& { int a; return a; }; // expected-warning {{reference to stack}}
+ (void) [&]() -> int& { int &a = b; return a; };
+ (void) [=]() mutable -> int& { int &a = b; return a; };
+}
diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp
index 580f0a7..98dbd51 100644
--- a/test/SemaCXX/return.cpp
+++ b/test/SemaCXX/return.cpp
@@ -102,3 +102,13 @@
}
};
}
+
+// rdar://15366494
+// pr17759
+namespace ctor_returns_void {
+ void f() {}
+ struct S {
+ S() { return f(); }; // expected-error {{constructor 'S' must not return void expression}}
+ ~S() { return f(); } // expected-error {{destructor '~S' must not return void expression}}
+ };
+}
diff --git a/test/SemaCXX/rval-references-examples.cpp b/test/SemaCXX/rval-references-examples.cpp
index 110ae26..8a5b562 100644
--- a/test/SemaCXX/rval-references-examples.cpp
+++ b/test/SemaCXX/rval-references-examples.cpp
@@ -4,7 +4,7 @@
class unique_ptr {
T *ptr;
- unique_ptr(const unique_ptr&) = delete; // expected-note 3{{function has been explicitly marked deleted here}}
+ unique_ptr(const unique_ptr&) = delete; // expected-note 3{{'unique_ptr' has been explicitly marked deleted here}}
unique_ptr &operator=(const unique_ptr&) = delete; // expected-note{{candidate function has been explicitly deleted}}
public:
unique_ptr() : ptr(0) { }
diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp
index 90c9317..c5fdb09 100644
--- a/test/SemaCXX/scope-check.cpp
+++ b/test/SemaCXX/scope-check.cpp
@@ -226,7 +226,7 @@
static void *ips[] = { &&l0 };
const C c0 = 17;
l0: // expected-note {{possible target of indirect goto}}
- const C &c1 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
+ const C &c1 = 42; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
const C &c2 = c0;
goto *ip; // expected-error {{indirect goto might cross protected scopes}}
}
@@ -241,7 +241,7 @@
void f(void **ip) {
static void *ips[] = { &&l0 };
l0: // expected-note {{possible target of indirect goto}}
- const int &c1 = C(1).i; // expected-note {{jump exits scope of variable with non-trivial destructor}}
+ const int &c1 = C(1).i; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
goto *ip; // expected-error {{indirect goto might cross protected scopes}}
}
}
@@ -295,6 +295,120 @@
}
#endif
+namespace test18 {
+ struct A { ~A(); };
+ struct B { const int &r; const A &a; };
+ int f() {
+ void *p = &&x;
+ const A a = A();
+ x:
+ B b = { 0, a }; // ok
+ goto *p;
+ }
+ int g() {
+ void *p = &&x;
+ x: // expected-note {{possible target of indirect goto}}
+ B b = { 0, A() }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
+ goto *p; // expected-error {{indirect goto might cross protected scopes}}
+ }
+}
+
+#if __cplusplus >= 201103L
+namespace std {
+ typedef decltype(sizeof(int)) size_t;
+ template<typename T> struct initializer_list {
+ const T *begin;
+ size_t size;
+ initializer_list(const T *, size_t);
+ };
+}
+namespace test19 {
+ struct A { ~A(); };
+
+ int f() {
+ void *p = &&x;
+ A a;
+ x: // expected-note {{possible target of indirect goto}}
+ std::initializer_list<A> il = { a }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
+ goto *p; // expected-error {{indirect goto might cross protected scopes}}
+ }
+}
+
+namespace test20 {
+ struct A { ~A(); };
+ struct B {
+ const A &a;
+ };
+
+ int f() {
+ void *p = &&x;
+ A a;
+ x:
+ std::initializer_list<B> il = {
+ a,
+ a
+ };
+ goto *p;
+ }
+ int g() {
+ void *p = &&x;
+ A a;
+ x: // expected-note {{possible target of indirect goto}}
+ std::initializer_list<B> il = {
+ a,
+ { A() } // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
+ };
+ goto *p; // expected-error {{indirect goto might cross protected scopes}}
+ }
+}
+#endif
+
+namespace test21 {
+ template<typename T> void f() {
+ goto x; // expected-error {{protected scope}}
+ T t; // expected-note {{bypasses}}
+ x: return;
+ }
+
+ template void f<int>();
+ struct X { ~X(); };
+ template void f<X>(); // expected-note {{instantiation of}}
+}
+
+namespace PR18217 {
+ typedef int *X;
+
+ template <typename T>
+ class MyCl {
+ T mem;
+ };
+
+ class Source {
+ MyCl<X> m;
+ public:
+ int getKind() const;
+ };
+
+ bool b;
+ template<typename TT>
+ static void foo(const Source &SF, MyCl<TT *> Source::*m) {
+ switch (SF.getKind()) {
+ case 1: return;
+ case 2: break;
+ case 3:
+ case 4: return;
+ };
+ if (b) {
+ auto &y = const_cast<MyCl<TT *> &>(SF.*m); // expected-warning 0-1{{extension}}
+ }
+ }
+
+ int Source::getKind() const {
+ foo(*this, &Source::m);
+ return 0;
+ }
+}
+
// This test must be last, because the error prohibits further jump diagnostics.
namespace testInvalid {
Invalid inv; // expected-error {{unknown type name}}
diff --git a/test/SemaCXX/sourceranges.cpp b/test/SemaCXX/sourceranges.cpp
index 1f25d5b..9ba003a 100644
--- a/test/SemaCXX/sourceranges.cpp
+++ b/test/SemaCXX/sourceranges.cpp
@@ -12,7 +12,7 @@
typedef int C;
}
-// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:16:1, col:36> ImplicitConstrArray 'foo::A [2]'
+// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:16:1, col:36> col:15 ImplicitConstrArray 'foo::A [2]'
static foo::A ImplicitConstrArray[2];
int main() {
@@ -28,3 +28,12 @@
// CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:10, col:17> 'foo::A'
return foo::A();
}
+
+void destruct(foo::A *a1, foo::A *a2, P<int> *p1) {
+ // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:8> '<bound member function type>' ->~A
+ a1->~A();
+ // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:16> '<bound member function type>' ->~A
+ a2->foo::A::~A();
+ // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:13> '<bound member function type>' ->~P
+ p1->~P<int>();
+}
diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp
index 7fb016e..06fd863 100644
--- a/test/SemaCXX/static-cast.cpp
+++ b/test/SemaCXX/static-cast.cpp
@@ -9,6 +9,8 @@
struct G1 : public B {};
struct G2 : public B {};
struct H : public G1, public G2 {}; // Ambiguous path to B.
+struct I; // Incomplete.
+struct J; // Incomplete.
enum Enum { En1, En2 };
enum Onom { On1, On2 };
@@ -131,6 +133,7 @@
// Bad code below
(void)static_cast<int A::*>((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
(void)static_cast<int A::*>((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
+ (void)static_cast<int I::*>((int J::*)0); // expected-error {{static_cast from 'int J::*' to 'int I::*' is not allowed}}
}
// PR 5261 - static_cast should instantiate template if possible
@@ -192,6 +195,6 @@
(void)static_cast<void (A::*)()>(&B::f);
(void)static_cast<void (B::*)()>(&B::f);
(void)static_cast<void (C::*)()>(&B::f);
- (void)static_cast<void (D::*)()>(&B::f); // expected-error{{address of overloaded function 'f' cannot be static_cast to type 'void (PR6072::D::*)()'}}
+ (void)static_cast<void (D::*)()>(&B::f); // expected-error-re{{address of overloaded function 'f' cannot be static_cast to type 'void (PR6072::D::*)(){{( __attribute__\(\(thiscall\)\))?}}'}}
}
}
diff --git a/test/SemaCXX/switch-implicit-fallthrough.cpp b/test/SemaCXX/switch-implicit-fallthrough.cpp
index d795923..831324a 100644
--- a/test/SemaCXX/switch-implicit-fallthrough.cpp
+++ b/test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -265,3 +265,16 @@
};
}
+namespace PR18983 {
+ void fatal() __attribute__((noreturn));
+ int num();
+ void test() {
+ switch (num()) {
+ case 1:
+ fatal();
+ // Don't issue a warning.
+ case 2:
+ break;
+ }
+ }
+}
diff --git a/test/SemaCXX/trailing-return-0x.cpp b/test/SemaCXX/trailing-return-0x.cpp
index f7e3433..cf5e659 100644
--- a/test/SemaCXX/trailing-return-0x.cpp
+++ b/test/SemaCXX/trailing-return-0x.cpp
@@ -17,7 +17,9 @@
return 0;
}
-auto g(); // expected-error{{return without trailing return type}}
+auto g(); // expected-error{{return without trailing return type; deduced return types are a C++1y extension}}
+decltype(auto) g2(); // expected-warning{{extension}} expected-error-re{{{{^}}deduced return types are a C++1y extension}}
+auto badness = g2();
int h() -> int; // expected-error{{trailing return type must specify return type 'auto', not 'int'}}
diff --git a/test/SemaCXX/type-definition-in-specifier.cpp b/test/SemaCXX/type-definition-in-specifier.cpp
index a614e6c..bda91d9 100644
--- a/test/SemaCXX/type-definition-in-specifier.cpp
+++ b/test/SemaCXX/type-definition-in-specifier.cpp
@@ -13,11 +13,11 @@
void f0() {
typedef struct S1 { int x; } S1_typedef;
- (void)((struct S2 { int x; }*)0); // expected-error{{can not be defined}}
+ (void)((struct S2 { int x; }*)0); // expected-error{{cannot be defined}}
struct S3 { int x; } s3;
- (void)static_cast<struct S4 { int x; } *>(0); // expected-error{{can not be defined}}
+ (void)static_cast<struct S4 { int x; } *>(0); // expected-error{{cannot be defined}}
}
struct S5 { int x; } f1() { return S5(); } // expected-error{{result type}}
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index 3e47921..28fb8dc 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -112,6 +112,14 @@
struct HasNoThrowConstructorWithArgs {
HasNoThrowConstructorWithArgs(HasCons i = HasCons(0)) throw();
};
+struct HasMultipleDefaultConstructor1 {
+ HasMultipleDefaultConstructor1() throw();
+ HasMultipleDefaultConstructor1(int i = 0);
+};
+struct HasMultipleDefaultConstructor2 {
+ HasMultipleDefaultConstructor2(int i = 0);
+ HasMultipleDefaultConstructor2() throw();
+};
struct HasNoThrowCopy { HasNoThrowCopy(const HasNoThrowCopy&) throw(); };
struct HasMultipleCopy {
@@ -1475,6 +1483,10 @@
{ int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyCtor))]; }
{ int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyAssign))]; }
{ int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToDtor))]; }
+
+
+ { int arr[T(__is_nothrow_assignable(HasNoThrowMoveAssign, HasNoThrowMoveAssign))]; }
+ { int arr[F(__is_nothrow_assignable(HasThrowMoveAssign, HasThrowMoveAssign))]; }
}
void has_trivial_move_assign() {
@@ -1562,6 +1574,9 @@
{ int arr[F(__has_nothrow_constructor(void))]; }
{ int arr[F(__has_nothrow_constructor(cvoid))]; }
{ int arr[F(__has_nothrow_constructor(HasTemplateCons))]; }
+
+ { int arr[F(__has_nothrow_constructor(HasMultipleDefaultConstructor1))]; }
+ { int arr[F(__has_nothrow_constructor(HasMultipleDefaultConstructor2))]; }
}
void has_virtual_destructor() {
@@ -1931,6 +1946,26 @@
TrivialMoveButNotCopy&&)))]; }
}
+void constructible_checks() {
+ { int arr[T(__is_constructible(HasNoThrowConstructorWithArgs))]; }
+ { int arr[F(__is_nothrow_constructible(HasNoThrowConstructorWithArgs))]; } // MSVC doesn't look into default args and gets this wrong.
+
+ { int arr[T(__is_constructible(HasNoThrowConstructorWithArgs, HasCons))]; }
+ { int arr[T(__is_nothrow_constructible(HasNoThrowConstructorWithArgs, HasCons))]; }
+
+ { int arr[T(__is_constructible(NonTrivialDefault))]; }
+ { int arr[F(__is_nothrow_constructible(NonTrivialDefault))]; }
+
+ { int arr[T(__is_constructible(int))]; }
+ { int arr[T(__is_nothrow_constructible(int))]; }
+
+ { int arr[F(__is_constructible(NonPOD))]; }
+ { int arr[F(__is_nothrow_constructible(NonPOD))]; }
+
+ { int arr[T(__is_constructible(NonPOD, int))]; }
+ { int arr[F(__is_nothrow_constructible(NonPOD, int))]; }
+}
+
// Instantiation of __is_trivially_constructible
template<typename T, typename ...Args>
struct is_trivially_constructible {
diff --git a/test/SemaCXX/typeid-ref.cpp b/test/SemaCXX/typeid-ref.cpp
index d01fd31..7e5dbdd 100644
--- a/test/SemaCXX/typeid-ref.cpp
+++ b/test/SemaCXX/typeid-ref.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
namespace std {
class type_info;
}
@@ -7,6 +7,6 @@
void f() {
// CHECK: @_ZTS1X = linkonce_odr constant
- // CHECK: @_ZTI1X = linkonce_odr unnamed_addr constant
+ // CHECK: @_ZTI1X = linkonce_odr constant
(void)typeid(X&);
}
diff --git a/test/SemaCXX/types_compatible_p.cpp b/test/SemaCXX/types_compatible_p.cpp
index 4aa9a1c..ebff53f 100644
--- a/test/SemaCXX/types_compatible_p.cpp
+++ b/test/SemaCXX/types_compatible_p.cpp
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s
+// RUN: %clang_cc1 -fsyntax-only -x c %s
-bool f() {
- return __builtin_types_compatible_p(int, const int); // expected-error{{C++}}
+// Test that GNU C extension __builtin_types_compatible_p() is not available in C++ mode.
+
+int f() {
+ return __builtin_types_compatible_p(int, const int); // expected-error{{}}
}
diff --git a/test/SemaCXX/typo-correction-pt2.cpp b/test/SemaCXX/typo-correction-pt2.cpp
index 525d11b..9943dd2 100644
--- a/test/SemaCXX/typo-correction-pt2.cpp
+++ b/test/SemaCXX/typo-correction-pt2.cpp
@@ -7,8 +7,8 @@
namespace bogus_keyword_suggestion {
void test() {
- status = "OK"; // expected-error-re {{use of undeclared identifier 'status'$}}
- return status; // expected-error-re {{use of undeclared identifier 'status'$}}
+ status = "OK"; // expected-error-re {{use of undeclared identifier 'status'{{$}}}}
+ return status; // expected-error-re {{use of undeclared identifier 'status'{{$}}}}
}
}
@@ -33,7 +33,7 @@
};
// should be void T::f();
void f() {
- data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'$}}
+ data_struct->foo(); // expected-error-re{{use of undeclared identifier 'data_struct'{{$}}}}
}
namespace PR12287 {
@@ -116,9 +116,9 @@
void testAccess() {
Figure obj;
switch (obj.type()) { // expected-warning {{enumeration values 'SQUARE', 'TRIANGLE', and 'CIRCLE' not handled in switch}}
- case SQUARE: // expected-error-re {{use of undeclared identifier 'SQUARE'$}}
- case TRIANGLE: // expected-error-re {{use of undeclared identifier 'TRIANGLE'$}}
- case CIRCE: // expected-error-re {{use of undeclared identifier 'CIRCE'$}}
+ case SQUARE: // expected-error-re {{use of undeclared identifier 'SQUARE'{{$}}}}
+ case TRIANGLE: // expected-error-re {{use of undeclared identifier 'TRIANGLE'{{$}}}}
+ case CIRCE: // expected-error-re {{use of undeclared identifier 'CIRCE'{{$}}}}
break;
}
}
@@ -126,13 +126,13 @@
long readline(const char *, char *, unsigned long);
void assign_to_unknown_var() {
- deadline_ = 1; // expected-error-re {{use of undeclared identifier 'deadline_'$}}
+ deadline_ = 1; // expected-error-re {{use of undeclared identifier 'deadline_'{{$}}}}
}
namespace no_ns_before_dot {
namespace re2 {}
void test() {
- req.set_check(false); // expected-error-re {{use of undeclared identifier 'req'$}}
+ req.set_check(false); // expected-error-re {{use of undeclared identifier 'req'{{$}}}}
}
}
@@ -199,3 +199,60 @@
PR18213::WrapperInfo ::PR18213::Wrappable<int>::kWrapperInfo = { 0 }; // expected-error {{no member named 'PR18213' in 'PR18213::WrapperInfo'; did you mean simply 'PR18213'?}} \
// expected-error {{C++ requires a type specifier for all declarations}}
}
+
+namespace PR18651 {
+struct {
+ int x;
+} a, b;
+
+int y = x; // expected-error-re {{use of undeclared identifier 'x'{{$}}}}
+}
+
+namespace PR18685 {
+template <class C, int I, int J>
+class SetVector {
+ public:
+ SetVector() {}
+};
+
+template <class C, int I>
+class SmallSetVector : public SetVector<C, I, 8> {};
+
+class foo {};
+SmallSetVector<foo*, 2> fooSet;
+}
+
+PR18685::BitVector Map; // expected-error-re {{no type named 'BitVector' in namespace 'PR18685'{{$}}}}
+
+namespace shadowed_template {
+template <typename T> class Fizbin {}; // expected-note {{'::shadowed_template::Fizbin' declared here}}
+class Baz {
+ int Fizbin();
+ // TODO: Teach the parser to recover from the typo correction instead of
+ // continuing to treat the template name as an implicit-int declaration.
+ Fizbin<int> qux; // expected-error {{unknown type name 'Fizbin'; did you mean '::shadowed_template::Fizbin'?}} \
+ // expected-error {{expected member name or ';' after declaration specifiers}}
+};
+}
+
+namespace PR18852 {
+void func() {
+ struct foo {
+ void bar() {}
+ };
+ bar(); // expected-error-re {{use of undeclared identifier 'bar'{{$}}}}
+}
+}
+
+namespace std {
+class bernoulli_distribution {
+ public:
+ double p() const;
+};
+}
+void test() {
+ // Make sure that typo correction doesn't suggest changing 'p' to
+ // 'std::bernoulli_distribution::p' as that is most likely wrong.
+ if (p) // expected-error-re {{use of undeclared identifier 'p'{{$}}}}
+ return;
+}
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 4047e6a..8541356 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -282,13 +282,13 @@
namespace b6956809_test2 {
template<typename T> struct Err { typename T::error n; }; // expected-error{{type 'void *' cannot be used prior to '::' because it has no members}}
struct S {
- template<typename T> typename Err<T>::type method(T); // expected-note{{in instantiation of template class 'b6956809_test2::Err<void *>' requested here}} expected-note{{while substituting deduced template arguments into function template 'method' [with T = void *]}}
+ template<typename T> typename Err<T>::type method(T); // expected-note{{in instantiation of template class 'b6956809_test2::Err<void *>' requested here}}
template<typename T> int method(T *);
};
void test() {
S s;
- int k = s.methodd((void*)0); // expected-error{{no member named 'methodd' in 'b6956809_test2::S'; did you mean 'method'?}}
+ int k = s.methodd((void*)0); // expected-error{{no member named 'methodd' in 'b6956809_test2::S'; did you mean 'method'?}} expected-note{{while substituting deduced template arguments into function template 'method' [with T = void *]}}
}
}
@@ -299,6 +299,6 @@
int flibberdy(); // expected-note{{'flibberdy' declared here}}
int no_correction() {
return hibberdy() + // expected-error{{use of undeclared identifier 'hibberdy'; did you mean 'flibberdy'?}}
- gibberdy(); // expected-error-re{{use of undeclared identifier 'gibberdy'$}}
+ gibberdy(); // expected-error-re{{use of undeclared identifier 'gibberdy'{{$}}}}
};
}
diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp
index 1b76a86..1cb0708 100644
--- a/test/SemaCXX/undefined-internal.cpp
+++ b/test/SemaCXX/undefined-internal.cpp
@@ -1,7 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// Make sure we don't produce invalid IR.
-// RUN: %clang_cc1 -emit-llvm-only %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s
+
+// FIXME: Itanium shouldn't be necessary; the test should pass
+// in MS mode too.
namespace test1 {
static void foo(); // expected-warning {{function 'test1::foo' has internal linkage but is not defined}}
@@ -15,9 +18,9 @@
namespace test2 {
namespace {
- void foo(); // expected-warning {{function 'test2::<anonymous namespace>::foo' has internal linkage but is not defined}}
- extern int var; // expected-warning {{variable 'test2::<anonymous namespace>::var' has internal linkage but is not defined}}
- template <class T> void bar(); // expected-warning {{function 'test2::<anonymous namespace>::bar<int>' has internal linkage but is not defined}}
+ void foo(); // expected-warning {{function 'test2::(anonymous namespace)::foo' has internal linkage but is not defined}}
+ extern int var; // expected-warning {{variable 'test2::(anonymous namespace)::var' has internal linkage but is not defined}}
+ template <class T> void bar(); // expected-warning {{function 'test2::(anonymous namespace)::bar<int>' has internal linkage but is not defined}}
}
void test() {
foo(); // expected-note {{used here}}
@@ -49,11 +52,11 @@
namespace test4 {
namespace {
struct A {
- A(); // expected-warning {{function 'test4::<anonymous namespace>::A::A' has internal linkage but is not defined}}
- ~A();// expected-warning {{function 'test4::<anonymous namespace>::A::~A' has internal linkage but is not defined}}
- virtual void foo(); // expected-warning {{function 'test4::<anonymous namespace>::A::foo' has internal linkage but is not defined}}
+ A(); // expected-warning {{function 'test4::(anonymous namespace)::A::A' has internal linkage but is not defined}}
+ ~A();// expected-warning {{function 'test4::(anonymous namespace)::A::~A' has internal linkage but is not defined}}
+ virtual void foo(); // expected-warning {{function 'test4::(anonymous namespace)::A::foo' has internal linkage but is not defined}}
virtual void bar() = 0;
- virtual void baz(); // expected-warning {{function 'test4::<anonymous namespace>::A::baz' has internal linkage but is not defined}}
+ virtual void baz(); // expected-warning {{function 'test4::(anonymous namespace)::A::baz' has internal linkage but is not defined}}
};
}
@@ -75,8 +78,8 @@
}
template <class N> struct B {
- static int var; // expected-warning {{variable 'test5::B<test5::<anonymous>::A>::var' has internal linkage but is not defined}}
- static void foo(); // expected-warning {{function 'test5::B<test5::<anonymous>::A>::foo' has internal linkage but is not defined}}
+ static int var; // expected-warning {{variable 'test5::B<test5::(anonymous namespace)::A>::var' has internal linkage but is not defined}}
+ static void foo(); // expected-warning {{function 'test5::B<test5::(anonymous namespace)::A>::foo' has internal linkage but is not defined}}
};
void test() {
@@ -175,7 +178,7 @@
namespace OverloadUse {
namespace {
void f();
- void f(int); // expected-warning {{function 'OverloadUse::<anonymous namespace>::f' has internal linkage but is not defined}}
+ void f(int); // expected-warning {{function 'OverloadUse::(anonymous namespace)::f' has internal linkage but is not defined}}
}
template<void x()> void t(int*) { x(); }
template<void x(int)> void t(long*) { x(10); } // expected-note {{used here}}
@@ -193,7 +196,7 @@
namespace test8 {
typedef struct {
- void bar(); // expected-warning {{function 'test8::<anonymous struct>::bar' has internal linkage but is not defined}}
+ void bar(); // expected-warning {{function 'test8::(anonymous struct)::bar' has internal linkage but is not defined}}
void foo() {
bar(); // expected-note {{used here}}
}
@@ -204,7 +207,7 @@
namespace {
struct X {
virtual void notused() = 0;
- virtual void used() = 0; // expected-warning {{function 'test9::<anonymous namespace>::X::used' has internal linkage but is not defined}}
+ virtual void used() = 0; // expected-warning {{function 'test9::(anonymous namespace)::X::used' has internal linkage but is not defined}}
};
}
void test(X &x) {
@@ -217,7 +220,7 @@
namespace {
struct X {
virtual void notused() = 0;
- virtual void used() = 0; // expected-warning {{function 'test10::<anonymous namespace>::X::used' has internal linkage but is not defined}}
+ virtual void used() = 0; // expected-warning {{function 'test10::(anonymous namespace)::X::used' has internal linkage but is not defined}}
void test() {
notused();
@@ -244,11 +247,11 @@
};
struct B {
- bool operator()() const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator()' has internal linkage but is not defined}}
- void operator!() const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator!' has internal linkage but is not defined}}
- bool operator+(const B&) const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator+' has internal linkage but is not defined}}
- int operator[](int) const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator[]' has internal linkage but is not defined}}
- const B* operator->() const; // expected-warning {{function 'test11::<anonymous namespace>::B::operator->' has internal linkage but is not defined}}
+ bool operator()() const; // expected-warning {{function 'test11::(anonymous namespace)::B::operator()' has internal linkage but is not defined}}
+ void operator!() const; // expected-warning {{function 'test11::(anonymous namespace)::B::operator!' has internal linkage but is not defined}}
+ bool operator+(const B&) const; // expected-warning {{function 'test11::(anonymous namespace)::B::operator+' has internal linkage but is not defined}}
+ int operator[](int) const; // expected-warning {{function 'test11::(anonymous namespace)::B::operator[]' has internal linkage but is not defined}}
+ const B* operator->() const; // expected-warning {{function 'test11::(anonymous namespace)::B::operator->' has internal linkage but is not defined}}
int member;
};
}
@@ -278,18 +281,18 @@
struct Cls {
virtual void f(int) = 0;
virtual void f(int, double) = 0;
- void g(int); // expected-warning {{function 'test12::<anonymous namespace>::Cls::g' has internal linkage but is not defined}}
+ void g(int); // expected-warning {{function 'test12::(anonymous namespace)::Cls::g' has internal linkage but is not defined}}
void g(int, double);
virtual operator T1() = 0;
virtual operator T2() = 0;
virtual operator T3&() = 0;
- operator T4(); // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T4' has internal linkage but is not defined}}
- operator T5(); // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T5' has internal linkage but is not defined}}
- operator T6&(); // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator class test12::T6 &' has internal linkage but is not defined}}
+ operator T4(); // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator T4' has internal linkage but is not defined}}
+ operator T5(); // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator T5' has internal linkage but is not defined}}
+ operator T6&(); // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator test12::T6 &' has internal linkage but is not defined}}
};
struct Cls2 {
- Cls2(T7); // expected-warning {{function 'test12::<anonymous namespace>::Cls2::Cls2' has internal linkage but is not defined}}
+ Cls2(T7); // expected-warning {{function 'test12::(anonymous namespace)::Cls2::Cls2' has internal linkage but is not defined}}
};
}
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index 4991ebe..677a141 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -117,7 +117,7 @@
A a20{a20}; // expected-warning {{variable 'a20' is uninitialized when used within its own initialization}}
A a21 = {a21}; // expected-warning {{variable 'a21' is uninitialized when used within its own initialization}}
- // FIXME: Make the local uninitialized warning consistant with the global
+ // FIXME: Make the local uninitialized warning consistent with the global
// uninitialized checking.
A *a22 = new A(a22->count); // expected-warning {{variable 'a22' is uninitialized when used within its own initialization}}
A *a23 = new A(a23->ONE); // expected-warning {{variable 'a23' is uninitialized when used within its own initialization}}
diff --git a/test/SemaCXX/unreachable-code.cpp b/test/SemaCXX/unreachable-code.cpp
index 743290e..fd006c0 100644
--- a/test/SemaCXX/unreachable-code.cpp
+++ b/test/SemaCXX/unreachable-code.cpp
@@ -1,17 +1,29 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -Wunreachable-code -fblocks -verify %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -Wunreachable-code-aggressive -fblocks -verify %s
int j;
-void bar() { }
+int bar();
int test1() {
for (int i = 0;
i != 10;
- ++i) { // expected-warning {{will never be executed}}
+ ++i) { // expected-warning {{loop will run at most once (loop increment never executed)}}
if (j == 23) // missing {}'s
bar();
return 1;
}
return 0;
- return 1; // expected-warning {{will never be executed}}
+ return 1; // expected-warning {{will never be executed}}
+}
+
+int test1_B() {
+ for (int i = 0;
+ i != 10;
+ ++i) { // expected-warning {{loop will run at most once (loop increment never executed)}}
+ if (j == 23) // missing {}'s
+ bar();
+ return 1;
+ }
+ return 0;
+ return bar(); // expected-warning {{will never be executed}}
}
void test2(int i) {
diff --git a/test/SemaCXX/vararg-class.cpp b/test/SemaCXX/vararg-class.cpp
new file mode 100644
index 0000000..08f521c
--- /dev/null
+++ b/test/SemaCXX/vararg-class.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -verify -Wclass-varargs -std=c++98 %s
+// RUN: %clang_cc1 -verify -Wclass-varargs -std=c++11 %s
+
+struct A {};
+struct B { ~B(); };
+class C { char *c_str(); };
+struct D { char *c_str(); };
+struct E { E(); };
+struct F { F(); char *c_str(); };
+
+void v(...);
+void w(const char*, ...) __attribute__((format(printf, 1, 2)));
+
+void test(A a, B b, C c, D d, E e, F f) {
+ v(a); // expected-warning-re {{passing object of class type 'A' through variadic function{{$}}}}
+ v(b); // expected-error-re {{cannot pass object of non-{{POD|trivial}} type 'B' through variadic function; call will abort at runtime}}
+ v(c); // expected-warning {{passing object of class type 'C' through variadic function; did you mean to call '.c_str()'?}}
+ v(d); // expected-warning {{passing object of class type 'D' through variadic function; did you mean to call '.c_str()'?}}
+ v(e);
+ v(f);
+#if __cplusplus < 201103L
+ // expected-error@-3 {{cannot pass object of non-POD type 'E' through variadic function; call will abort at runtime}}
+ // expected-error@-3 {{cannot pass object of non-POD type 'F' through variadic function; call will abort at runtime}}
+#else
+ // expected-warning-re@-6 {{passing object of class type 'E' through variadic function{{$}}}}
+ // expected-warning@-6 {{passing object of class type 'F' through variadic function; did you mean to call '.c_str()'?}}
+#endif
+
+ v(d.c_str());
+ v(f.c_str());
+ v(0);
+ v('x');
+
+ w("%s", a); // expected-warning {{format specifies type 'char *' but the argument has type 'A'}}
+ w("%s", b); // expected-error-re {{cannot pass non-{{POD|trivial}} object of type 'B' to variadic function; expected type from format string was 'char *'}}
+ w("%s", c); // expected-warning {{format specifies type 'char *' but the argument has type 'C'}}
+ w("%s", d); // expected-warning {{format specifies type 'char *' but the argument has type 'D'}}
+ w("%s", e);
+ w("%s", f);
+#if __cplusplus < 201103L
+ // expected-error@-3 {{cannot pass non-POD object of type 'E' to variadic function; expected type from format string was 'char *'}}
+ // expected-error@-3 {{cannot pass non-POD object of type 'F' to variadic function; expected type from format string was 'char *'}}
+ // expected-note@-4 {{did you mean to call the c_str() method?}}
+#else
+ // expected-warning@-7 {{format specifies type 'char *' but the argument has type 'E'}}
+ // expected-warning@-7 {{format specifies type 'char *' but the argument has type 'F'}}
+#endif
+}
diff --git a/test/SemaCXX/vector-casts.cpp b/test/SemaCXX/vector-casts.cpp
index 681a07e..3aa097b 100644
--- a/test/SemaCXX/vector-casts.cpp
+++ b/test/SemaCXX/vector-casts.cpp
@@ -2,6 +2,7 @@
typedef int __v2si __attribute__((__vector_size__(8)));
typedef short __v4hi __attribute__((__vector_size__(8)));
typedef short __v8hi __attribute__((__vector_size__(16)));
+typedef short __v3hi __attribute__((__ext_vector_type__(3)));
struct S { }; // expected-note 2 {{candidate constructor}}
@@ -37,4 +38,28 @@
(void)(__v4hi)v8hi; // expected-error {{C-style cast from vector '__v8hi' to vector '__v4hi' of different size}}
}
+struct testvec {
+ __v2si v;
+ void madd(const testvec& rhs) {
+ v = v + rhs; // expected-error {{can't convert between vector and non-scalar values}}
+ }
+ void madd2(testvec rhs) {
+ v = v + rhs; // expected-error {{can't convert between vector and non-scalar values}}
+ }
+};
+// rdar://15931426
+// Conversions for return values.
+__v4hi threeToFour(__v3hi v) { // expected-note {{not viable}}
+ return v; // expected-error {{cannot initialize return object}}
+}
+__v3hi fourToThree(__v4hi v) { // expected-note {{not viable}}
+ return v; // expected-error {{cannot initialize return object}}
+}
+// Conversions for calls.
+void call3to4(__v4hi v) {
+ (void) threeToFour(v); // expected-error {{no matching function for call}}
+}
+void call4to3(__v3hi v) {
+ (void) fourToThree(v); // expected-error {{no matching function for call}}
+}
diff --git a/test/SemaCXX/virtual-base-used.cpp b/test/SemaCXX/virtual-base-used.cpp
index 04518ce..c46cf5a 100644
--- a/test/SemaCXX/virtual-base-used.cpp
+++ b/test/SemaCXX/virtual-base-used.cpp
@@ -1,42 +1,89 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %s
// PR7800
+// The Microsoft ABI doesn't have the concept of key functions, so we have different
+// expectations about when functions are first required for that case.
+
+#ifdef MSABI
+// expected-note@+2 3 {{declared private here}}
+#endif
class NoDestroy { ~NoDestroy(); }; // expected-note 3 {{declared private here}}
struct A {
virtual ~A();
};
+#ifdef MSABI
+// expected-error@+3 {{field of type 'NoDestroy' has private destructor}}
+#endif
struct B : public virtual A {
NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
};
+#ifdef MSABI
+// expected-note@+3 {{implicit default constructor for 'B' first required here}}
+// expected-note@+2 {{implicit destructor for 'B' first required here}}
+#endif
struct D : public virtual B {
virtual void foo();
~D();
};
+#ifdef MSABI
+D d; // expected-note {{implicit default constructor for 'D' first required here}}
+#else
void D::foo() { // expected-note {{implicit destructor for 'B' first required here}}
}
+#endif
+#ifdef MSABI
+// expected-error@+3 {{field of type 'NoDestroy' has private destructor}}
+#endif
struct E : public virtual A {
NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
};
+#ifdef MSABI
+// expected-note@+2 {{implicit default constructor for 'E' first required here}}
+#endif
struct F : public E { // expected-note {{implicit destructor for 'E' first required here}}
};
+#ifdef MSABI
+// expected-note@+2 {{implicit default constructor for 'F' first required here}}
+#endif
struct G : public virtual F {
virtual void foo();
~G();
};
+#ifdef MSABI
+G g; // expected-note {{implicit default constructor for 'G' first required here}}
+#else
void G::foo() { // expected-note {{implicit destructor for 'F' first required here}}
}
+#endif
+#ifdef MSABI
+// expected-note@+3 {{'H' declared here}}
+// expected-error@+3 {{field of type 'NoDestroy' has private destructor}}
+#endif
struct H : public virtual A {
NoDestroy x; // expected-error {{field of type 'NoDestroy' has private destructor}}
};
+#ifdef MSABI
+// expected-error@+3 {{implicit default constructor for 'I' must explicitly initialize the base class 'H' which does not have a default constructor}}
+// expected-note@+2 {{implicit destructor for 'H' first required here}}
+#endif
struct I : public virtual H {
~I();
};
+#ifdef MSABI
+// expected-note@+3 {{implicit default constructor for 'H' first required here}}
+// expected-note@+2 {{implicit default constructor for 'I' first required here}}
+#endif
struct J : public I {
virtual void foo();
~J();
};
+#ifdef MSABI
+J j; // expected-note {{implicit default constructor for 'J' first required here}}
+#else
void J::foo() { // expected-note {{implicit destructor for 'H' first required here}}
}
+#endif
diff --git a/test/SemaCXX/virtual-override-x86.cpp b/test/SemaCXX/virtual-override-x86.cpp
index 75d8af3..1d9d1fb 100644
--- a/test/SemaCXX/virtual-override-x86.cpp
+++ b/test/SemaCXX/virtual-override-x86.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple=i686-pc-unknown -fsyntax-only -verify %s -std=c++11 -cxx-abi microsoft
+// RUN: %clang_cc1 -triple=i686-pc-win32 -fsyntax-only -verify %s -std=c++11
namespace PR14339 {
class A {
diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp
index b477438..e95acab 100644
--- a/test/SemaCXX/virtual-override.cpp
+++ b/test/SemaCXX/virtual-override.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -verify %s -std=c++11
namespace T1 {
class A {
diff --git a/test/SemaCXX/vla.cpp b/test/SemaCXX/vla.cpp
index d63b633..dae6450 100644
--- a/test/SemaCXX/vla.cpp
+++ b/test/SemaCXX/vla.cpp
@@ -3,3 +3,17 @@
// PR11925
int n;
int (&f())[n]; // expected-error {{function declaration cannot have variably modified type}}
+
+namespace PR18581 {
+ template<typename T> struct pod {};
+ template<typename T> struct error {
+ typename T::error e; // expected-error {{cannot be used prior to '::'}}
+ };
+ struct incomplete; // expected-note {{forward declaration}}
+
+ void f(int n) {
+ pod<int> a[n];
+ error<int> b[n]; // expected-note {{instantiation}}
+ incomplete c[n]; // expected-error {{incomplete}}
+ }
+}
diff --git a/test/SemaCXX/vtordisp-mode.cpp b/test/SemaCXX/vtordisp-mode.cpp
new file mode 100644
index 0000000..dc91534
--- /dev/null
+++ b/test/SemaCXX/vtordisp-mode.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -vtordisp-mode=0 -DVTORDISP_MODE=0 %s -verify
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -vtordisp-mode=1 -DVTORDISP_MODE=1 %s -verify
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -vtordisp-mode=2 -DVTORDISP_MODE=2 %s -verify
+
+// expected-no-diagnostics
+
+struct A {
+ A();
+ virtual void foo();
+};
+
+// At /vd1, there is a vtordisp before A.
+struct B : virtual A {
+ B();
+ virtual void foo();
+ virtual void bar();
+};
+
+// At /vd2, there is a vtordisp before B, but only because it has its own
+// vftable.
+struct C : virtual B {
+ C();
+};
+
+// There are two vfptrs, two vbptrs, and some number of vtordisps.
+static_assert(sizeof(C) == 2 * 4 + 2 * 4 + 4 * VTORDISP_MODE, "size mismatch");
diff --git a/test/SemaCXX/warn-absolute-value-header.cpp b/test/SemaCXX/warn-absolute-value-header.cpp
new file mode 100644
index 0000000..01aaabc
--- /dev/null
+++ b/test/SemaCXX/warn-absolute-value-header.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s -Wabsolute-value
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only %s -Wabsolute-value -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+
+extern "C" int abs(int);
+
+// Wrong signature
+int fabsf(int);
+
+void test_int(int i, unsigned u, long long ll, float f, double d) {
+ (void)abs(i);
+
+ // Remove abs call
+ (void)abs(u);
+ // expected-warning@-1{{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+ // expected-note@-2{{remove the call to 'abs' since unsigned values cannot be negative}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:""
+
+ int llabs;
+ (void)llabs;
+ // Conflict in names, suggest qualified name
+ (void)abs(ll);
+ // expected-warning@-1{{absolute value function 'abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value}}
+ // expected-note@-2{{use function '::llabs' instead}}
+ // expected-note@-3{{please include the header <stdlib.h> or explicitly provide a declaration for 'llabs'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:12}:"::llabs"
+
+ // Conflict in names, no notes
+ (void)abs(f);
+ // expected-warning@-1{{using integer absolute value function 'abs' when argument is of floating point type}}
+
+ // Suggest header.
+ (void)abs(d);
+ // expected-warning@-1{{using integer absolute value function 'abs' when argument is of floating point type}}
+ // expected-note@-2{{use function 'fabs' instead}}
+ // expected-note@-3{{please include the header <math.h> or explicitly provide a declaration for 'fabs'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:12}:"fabs"
+}
diff --git a/test/SemaCXX/warn-absolute-value2.cpp b/test/SemaCXX/warn-absolute-value2.cpp
new file mode 100644
index 0000000..5f7e891
--- /dev/null
+++ b/test/SemaCXX/warn-absolute-value2.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s -Wabsolute-value
+
+extern "C" {
+int abs(int);
+double fabs(double);
+}
+
+using ::fabs;
+
+double test(double x) {
+ return ::abs(x);
+ // expected-warning@-1{{using integer absolute value function 'abs' when argument is of floating point type}}
+}
diff --git a/test/SemaCXX/warn-address.cpp b/test/SemaCXX/warn-address.cpp
new file mode 100644
index 0000000..219edfd
--- /dev/null
+++ b/test/SemaCXX/warn-address.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion -Wno-string-compare -Wno-tautological-compare -Waddress %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void foo();
+int arr[5];
+int global;
+const char* str = "";
+
+void test() {
+ if (foo) {} // expected-warning{{always evaluate to 'true'}} \
+ // expected-note{{silence}}
+ if (arr) {} // expected-warning{{always evaluate to 'true'}}
+ if (&global) {} // expected-warning{{always evaluate to 'true'}}
+ if (foo == 0) {} // expected-warning{{always false}} \
+ // expected-note{{silence}}
+ if (arr == 0) {} // expected-warning{{always false}}
+ if (&global == 0) {} // expected-warning{{always false}}
+
+ if (str == "foo") {} // expected-warning{{unspecified}}
+}
diff --git a/test/SemaCXX/warn-bool-conversion.cpp b/test/SemaCXX/warn-bool-conversion.cpp
index b3d136e..b462894 100644
--- a/test/SemaCXX/warn-bool-conversion.cpp
+++ b/test/SemaCXX/warn-bool-conversion.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace BooleanFalse {
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}}
@@ -22,3 +23,98 @@
// isn't flagged.
template <int N> struct S {};
S<sizeof(f(false))> s;
+
+}
+
+namespace Function {
+void f1();
+
+struct S {
+ static void f2();
+};
+
+extern void f3() __attribute__((weak_import));
+
+struct S2 {
+ static void f4() __attribute__((weak_import));
+};
+
+bool f5();
+bool f6(int);
+
+void bar() {
+ bool b;
+
+ b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+ b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}} \
+ expected-note {{suffix with parentheses to turn this into a function call}}
+ b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
+ expected-note {{prefix with the address-of operator to silence this warning}}
+
+ // implicit casts of weakly imported symbols are ok:
+ b = f3;
+ if (f3) {}
+ b = S2::f4;
+ if (S2::f4) {}
+}
+}
+
+namespace Array {
+ #define GetValue(ptr) ((ptr) ? ptr[0] : 0)
+ extern int a[] __attribute__((weak));
+ int b[] = {8,13,21};
+ struct {
+ int x[10];
+ } c;
+ const char str[] = "text";
+ void ignore() {
+ if (a) {}
+ if (a) {}
+ (void)GetValue(b);
+ }
+ void test() {
+ if (b) {}
+ // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
+ if (b) {}
+ // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
+ if (c.x) {}
+ // expected-warning@-1{{address of array 'c.x' will always evaluate to 'true'}}
+ if (str) {}
+ // expected-warning@-1{{address of array 'str' will always evaluate to 'true'}}
+ }
+}
+
+namespace Pointer {
+ extern int a __attribute__((weak));
+ int b;
+ static int c;
+ class S {
+ public:
+ static int a;
+ int b;
+ };
+ void ignored() {
+ if (&a) {}
+ }
+ void test() {
+ S s;
+ if (&b) {}
+ // expected-warning@-1{{address of 'b' will always evaluate to 'true'}}
+ if (&c) {}
+ // expected-warning@-1{{address of 'c' will always evaluate to 'true'}}
+ if (&s.a) {}
+ // expected-warning@-1{{address of 's.a' will always evaluate to 'true'}}
+ if (&s.b) {}
+ // expected-warning@-1{{address of 's.b' will always evaluate to 'true'}}
+ if (&S::a) {}
+ // expected-warning@-1{{address of 'S::a' will always evaluate to 'true'}}
+ }
+}
diff --git a/test/SemaCXX/warn-consumed-analysis.cpp b/test/SemaCXX/warn-consumed-analysis.cpp
index 64fdc00..bd091c6 100644
--- a/test/SemaCXX/warn-consumed-analysis.cpp
+++ b/test/SemaCXX/warn-consumed-analysis.cpp
@@ -51,7 +51,7 @@
class CONSUMABLE(unconsumed) DestructorTester {
public:
- DestructorTester() RETURN_TYPESTATE(unconsumed);
+ DestructorTester();
DestructorTester(int);
void operator*() CALLABLE_WHEN("unconsumed");
@@ -82,11 +82,21 @@
void testInitialization() {
ConsumableClass<int> var0;
ConsumableClass<int> var1 = ConsumableClass<int>();
-
- var0 = ConsumableClass<int>();
-
+ ConsumableClass<int> var2(42);
+ ConsumableClass<int> var3(var2); // copy constructor
+ ConsumableClass<int> var4(var0); // copy consumed value
+
*var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
*var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+ *var2;
+ *var3;
+ *var4; // expected-warning {{invalid invocation of method 'operator*' on object 'var4' while it is in the 'consumed' state}}
+
+ var0 = ConsumableClass<int>(42);
+ *var0;
+
+ var0 = var1;
+ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
if (var0.isValid()) {
*var0;
@@ -98,19 +108,16 @@
}
void testDestruction() {
- DestructorTester D0(42), D1(42);
+ DestructorTester D0(42), D1(42), D2;
*D0;
*D1;
-
- DestructorTester D2;
- *D2;
+ *D2; // expected-warning {{invalid invocation of method 'operator*' on object 'D2' while it is in the 'consumed' state}}
D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \
- expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}} \
- expected-warning {{invalid invocation of method '~DestructorTester' on object 'D2' while it is in the 'unconsumed' state}}
+ expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
}
void testTempValue() {
@@ -427,6 +434,29 @@
testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
}
+
+void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+struct ParamTest {
+ static void consumeFuncStatic(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+ void consumeFuncMeth(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+ void operator<<(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+};
+
+void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+
+
+void testFunctionParams() {
+ // Make sure we handle the different kinds of functions.
+ ConsumableClass<int> P;
+
+ consumeFunc(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ ParamTest::consumeFuncStatic(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ ParamTest pt;
+ pt.consumeFuncMeth(P); // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ pt << P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+ pt >> P; // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+}
+
void baf3(ConsumableClass<int> var) {
*var;
}
@@ -645,12 +675,17 @@
} // end namespace ContinueICETest
-namespace InitializerAssertionFailTest {
+namespace StatusUseCaseTests {
-class CONSUMABLE(unconsumed) Status {
+class CONSUMABLE(unconsumed)
+ __attribute__((consumable_auto_cast_state))
+ __attribute__((consumable_set_state_on_read))
+ Status {
int code;
public:
+ static Status OK;
+
Status() RETURN_TYPESTATE(consumed);
Status(int c) RETURN_TYPESTATE(unconsumed);
@@ -660,6 +695,8 @@
Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
+ bool operator==(const Status &other) const SET_TYPESTATE(consumed);
+
bool check() const SET_TYPESTATE(consumed);
void ignore() const SET_TYPESTATE(consumed);
// Status& markAsChecked() { return *this; }
@@ -673,7 +710,14 @@
bool cond();
Status doSomething();
void handleStatus(const Status& s RETURN_TYPESTATE(consumed));
-void handleStatusPtr(const Status* s);
+void handleStatusRef(Status& s);
+void handleStatusPtr(Status* s);
+void handleStatusUnmarked(const Status& s);
+
+void log(const char* msg);
+void fail() __attribute__((noreturn));
+void checkStat(const Status& s);
+
void testSimpleTemporaries0() {
doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
@@ -691,6 +735,15 @@
Status s = doSomething();
} // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
+Status testSimpleTemporariesReturn0() {
+ return doSomething();
+}
+
+Status testSimpleTemporariesReturn1() {
+ Status s = doSomething();
+ return s;
+}
+
void testSimpleTemporaries4() {
Status s = doSomething();
s.check();
@@ -702,8 +755,17 @@
}
void testSimpleTemporaries6() {
- Status s = doSomething();
- handleStatus(s);
+ Status s1 = doSomething();
+ handleStatus(s1);
+
+ Status s2 = doSomething();
+ handleStatusRef(s2);
+
+ Status s3 = doSomething();
+ handleStatusPtr(&s3);
+
+ Status s4 = doSomething();
+ handleStatusUnmarked(s4);
}
void testSimpleTemporaries7() {
@@ -745,38 +807,58 @@
}
void testTemporariesAndConstructors0() {
- Status s(doSomething());
+ Status s(doSomething()); // Test the copy constructor.
s.check();
}
-void testTemporariesAndConstructors1() {
- // Test the copy constructor.
-
- Status s1 = doSomething();
- Status s2(s1);
- s2.check();
-} // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}}
+void testTemporariesAndConstructors1F() {
+ Status s1 = doSomething(); // Test the copy constructor.
+ Status s2 = s1;
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
-void testTemporariesAndConstructors2() {
- // Test the move constructor.
-
- Status s1 = doSomething();
- Status s2(static_cast<Status&&>(s1));
+void testTemporariesAndConstructors1S() {
+ Status s1 = doSomething(); // Test the copy constructor.
+ Status s2(s1);
s2.check();
}
-void testTemporariesAndOperators0() {
+void testTemporariesAndConstructors2F() {
+ // Test the move constructor.
+ Status s1 = doSomething();
+ Status s2 = static_cast<Status&&>(s1);
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndConstructors2S() {
+ // Test the move constructor.
+ Status s1 = doSomething();
+ Status s2 = static_cast<Status&&>(s1);
+ s2.check();
+}
+
+void testTemporariesAndOperators0F() {
// Test the assignment operator.
-
+ Status s1 = doSomething();
+ Status s2;
+ s2 = s1;
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndOperators0S() {
+ // Test the assignment operator.
Status s1 = doSomething();
Status s2;
s2 = s1;
s2.check();
-} // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}}
+}
-void testTemporariesAndOperators1() {
+void testTemporariesAndOperators1F() {
// Test the move assignment operator.
-
+ Status s1 = doSomething();
+ Status s2;
+ s2 = static_cast<Status&&>(s1);
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndOperators1S() {
+ // Test the move assignment operator.
Status s1 = doSomething();
Status s2;
s2 = static_cast<Status&&>(s1);
@@ -791,5 +873,62 @@
s2.check();
}
+Status testReturnAutocast() {
+ Status s = doSomething();
+ s.check(); // consume s
+ return s; // should autocast back to unconsumed
+}
+
+
+namespace TestParens {
+
+void test3() {
+ checkStat((doSomething()));
+}
+
+void test4() {
+ Status s = (doSomething());
+ s.check();
+}
+
+void test5() {
+ (doSomething()).check();
+}
+
+void test6() {
+ if ((doSomething()) == Status::OK)
+ return;
+}
+
+} // end namespace TestParens
+
} // end namespace InitializerAssertionFailTest
+
+namespace std {
+ void move();
+ template<class T>
+ void move(T&&);
+
+ namespace __1 {
+ void move();
+ template<class T>
+ void move(T&&);
+ }
+}
+
+namespace PR18260 {
+ class X {
+ public:
+ void move();
+ } x;
+
+ void test() {
+ x.move();
+ std::move();
+ std::move(x);
+ std::__1::move();
+ std::__1::move(x);
+ }
+} // end namespace PR18260
+
diff --git a/test/SemaCXX/warn-consumed-parsing.cpp b/test/SemaCXX/warn-consumed-parsing.cpp
index 0a91636..5c0a04f 100644
--- a/test/SemaCXX/warn-consumed-parsing.cpp
+++ b/test/SemaCXX/warn-consumed-parsing.cpp
@@ -17,9 +17,9 @@
}
class AttrTester0 {
- void consumes() __attribute__ ((set_typestate())); // expected-error {{attribute takes one argument}}
- bool testUnconsumed() __attribute__ ((test_typestate())); // expected-error {{attribute takes one argument}}
- void callableWhen() __attribute__ ((callable_when())); // expected-error {{attribute takes at least 1 argument}}
+ void consumes() __attribute__ ((set_typestate())); // expected-error {{'set_typestate' attribute takes one argument}}
+ bool testUnconsumed() __attribute__ ((test_typestate())); // expected-error {{'test_typestate' attribute takes one argument}}
+ void callableWhen() __attribute__ ((callable_when())); // expected-error {{'callable_when' attribute takes at least 1 argument}}
};
int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}}
@@ -53,3 +53,13 @@
};
class CONSUMABLE(42) AttrTester3; // expected-error {{'consumable' attribute requires an identifier}}
+
+
+class CONSUMABLE(unconsumed)
+ __attribute__((consumable_auto_cast_state))
+ __attribute__((consumable_set_state_on_read))
+ Status {
+};
+
+
+
diff --git a/test/SemaCXX/warn-exit-time-destructors.cpp b/test/SemaCXX/warn-exit-time-destructors.cpp
index f49134b..124576a 100644
--- a/test/SemaCXX/warn-exit-time-destructors.cpp
+++ b/test/SemaCXX/warn-exit-time-destructors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wexit-time-destructors %s -verify
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wexit-time-destructors %s -verify
namespace test1 {
struct A { ~A(); };
@@ -23,5 +23,23 @@
static A &e = b[5];
static A &f = c[5][7];
}
+}
+namespace test3 {
+ struct A { ~A() = default; };
+ A a;
+
+ struct B { ~B(); };
+ struct C : B { ~C() = default; };
+ C c; // expected-warning {{exit-time destructor}}
+
+ class D {
+ friend struct E;
+ ~D() = default;
+ };
+ struct E : D {
+ D d;
+ ~E() = default;
+ };
+ E e;
}
diff --git a/test/SemaCXX/warn-func-as-bool.cpp b/test/SemaCXX/warn-func-as-bool.cpp
deleted file mode 100644
index b5df744..0000000
--- a/test/SemaCXX/warn-func-as-bool.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -x c++ -verify -fsyntax-only %s
-
-void f1();
-
-struct S {
- static void f2();
-};
-
-extern void f3() __attribute__((weak_import));
-
-struct S2 {
- static void f4() __attribute__((weak_import));
-};
-
-bool f5();
-bool f6(int);
-
-void bar() {
- bool b;
-
- b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
- b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}} \
- expected-note {{suffix with parentheses to turn this into a function call}}
- b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
- expected-note {{prefix with the address-of operator to silence this warning}}
-
- // implicit casts of weakly imported symbols are ok:
- b = f3;
- if (f3) {}
- b = S2::f4;
- if (S2::f4) {}
-}
diff --git a/test/SemaCXX/warn-global-constructors.cpp b/test/SemaCXX/warn-global-constructors.cpp
index f57f0de..90d8558 100644
--- a/test/SemaCXX/warn-global-constructors.cpp
+++ b/test/SemaCXX/warn-global-constructors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wglobal-constructors %s -verify
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wglobal-constructors %s -verify
int opaque_int();
@@ -101,3 +101,22 @@
int a;
A b = { a };
}
+
+namespace pr19253 {
+ struct A { ~A() = default; };
+ A a;
+
+ struct B { ~B(); };
+ struct C : B { ~C() = default; };
+ C c; // expected-warning {{global destructor}}
+
+ class D {
+ friend struct E;
+ ~D() = default;
+ };
+ struct E : D {
+ D d;
+ ~E() = default;
+ };
+ E e;
+}
diff --git a/test/SemaCXX/warn-infinite-recursion.cpp b/test/SemaCXX/warn-infinite-recursion.cpp
new file mode 100644
index 0000000..e1b7c54
--- /dev/null
+++ b/test/SemaCXX/warn-infinite-recursion.cpp
@@ -0,0 +1,152 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion
+
+void a() { // expected-warning{{call itself}}
+ a();
+}
+
+void b(int x) { // expected-warning{{call itself}}
+ if (x)
+ b(x);
+ else
+ b(x+1);
+}
+
+void c(int x) {
+ if (x)
+ c(5);
+}
+
+void d(int x) { // expected-warning{{call itself}}
+ if (x)
+ ++x;
+ return d(x);
+}
+
+// Doesn't warn on mutually recursive functions
+void e();
+void f();
+
+void e() { f(); }
+void f() { e(); }
+
+// Don't warn on infinite loops
+void g() {
+ while (true)
+ g();
+
+ g();
+}
+
+void h(int x) {
+ while (x < 5) {
+ h(x+1);
+ }
+}
+
+void i(int x) { // expected-warning{{call itself}}
+ while (x < 5) {
+ --x;
+ }
+ i(0);
+}
+
+int j() { // expected-warning{{call itself}}
+ return 5 + j();
+}
+
+class S {
+ static void a();
+ void b();
+};
+
+void S::a() { // expected-warning{{call itself}}
+ return a();
+}
+
+void S::b() { // expected-warning{{call itself}}
+ int i = 0;
+ do {
+ ++i;
+ b();
+ } while (i > 5);
+}
+
+template<class member>
+struct T {
+ member m;
+ void a() { return a(); } // expected-warning{{call itself}}
+ static void b() { return b(); } // expected-warning{{call itself}}
+};
+
+void test_T() {
+ T<int> foo;
+ foo.a(); // expected-note{{in instantiation}}
+ foo.b(); // expected-note{{in instantiation}}
+}
+
+class U {
+ U* u;
+ void Fun() { // expected-warning{{call itself}}
+ u->Fun();
+ }
+};
+
+// No warnings on templated functions
+// sum<0>() is instantiated, does recursively call itself, but never runs.
+template <int value>
+int sum() {
+ return value + sum<value/2>();
+}
+
+template<>
+int sum<1>() { return 1; }
+
+template<int x, int y>
+int calculate_value() {
+ if (x != y)
+ return sum<x - y>(); // This instantiates sum<0>() even if never called.
+ else
+ return 0;
+}
+
+int value = calculate_value<1,1>();
+
+void DoSomethingHere();
+
+// DoStuff<0,0>() is instantiated, but never called.
+template<int First, int Last>
+int DoStuff() {
+ if (First + 1 == Last) {
+ // This branch gets removed during <0, 0> instantiation in so CFG for this
+ // function goes straight to the else branch.
+ DoSomethingHere();
+ } else {
+ DoStuff<First, (First + Last)/2>();
+ DoStuff<(First + Last)/2, Last>();
+ }
+ return 0;
+}
+int stuff = DoStuff<0, 1>();
+
+template<int x>
+struct Wrapper {
+ static int run() {
+ // Similar to the above, Wrapper<0>::run() will discard the if statement.
+ if (x == 1)
+ return 0;
+ return Wrapper<x/2>::run();
+ }
+ static int run2() { // expected-warning{{call itself}}
+ return run2();
+ }
+};
+
+template <int x>
+int test_wrapper() {
+ if (x != 0)
+ return Wrapper<x>::run() +
+ Wrapper<x>::run2(); // expected-note{{instantiation}}
+ return 0;
+}
+
+int wrapper_sum = test_wrapper<2>(); // expected-note{{instantiation}}
diff --git a/test/SemaCXX/warn-memsize-comparison.cpp b/test/SemaCXX/warn-memsize-comparison.cpp
new file mode 100644
index 0000000..54c410e
--- /dev/null
+++ b/test/SemaCXX/warn-memsize-comparison.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+//
+
+typedef __SIZE_TYPE__ size_t;
+extern "C" void *memset(void *, int, size_t);
+extern "C" void *memmove(void *s1, const void *s2, size_t n);
+extern "C" void *memcpy(void *s1, const void *s2, size_t n);
+extern "C" void *memcmp(void *s1, const void *s2, size_t n);
+extern "C" int strncmp(const char *s1, const char *s2, size_t n);
+extern "C" int strncasecmp(const char *s1, const char *s2, size_t n);
+extern "C" char *strncpy(char *dst, const char *src, size_t n);
+extern "C" char *strncat(char *dst, const char *src, size_t n);
+extern "C" char *strndup(const char *src, size_t n);
+extern "C" size_t strlcpy(char *dst, const char *src, size_t size);
+extern "C" size_t strlcat(char *dst, const char *src, size_t size);
+
+void f() {
+ char b1[80], b2[80];
+ if (memset(b1, 0, sizeof(b1) != 0)) {} // \
+ expected-warning{{size argument in 'memset' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (memset(b1, 0, sizeof(b1)) != 0) {}
+
+ if (memmove(b1, b2, sizeof(b1) == 0)) {} // \
+ expected-warning{{size argument in 'memmove' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (memmove(b1, b2, sizeof(b1)) == 0) {}
+
+ if (memcpy(b1, b2, sizeof(b1) < 0)) {} // \
+ expected-warning{{size argument in 'memcpy' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (memcpy(b1, b2, sizeof(b1)) < 0) {}
+
+ if (memcmp(b1, b2, sizeof(b1) <= 0)) {} // \
+ expected-warning{{size argument in 'memcmp' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (memcmp(b1, b2, sizeof(b1)) <= 0) {}
+
+ if (strncmp(b1, b2, sizeof(b1) > 0)) {} // \
+ expected-warning{{size argument in 'strncmp' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strncmp(b1, b2, sizeof(b1)) > 0) {}
+
+ if (strncasecmp(b1, b2, sizeof(b1) >= 0)) {} // \
+ expected-warning{{size argument in 'strncasecmp' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strncasecmp(b1, b2, sizeof(b1)) >= 0) {}
+
+ if (strncpy(b1, b2, sizeof(b1) == 0 || true)) {} // \
+ expected-warning{{size argument in 'strncpy' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strncpy(b1, b2, sizeof(b1)) == 0 || true) {}
+
+ if (strncat(b1, b2, sizeof(b1) - 1 >= 0 && true)) {} // \
+ expected-warning{{size argument in 'strncat' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strncat(b1, b2, sizeof(b1) - 1) >= 0 && true) {}
+
+ if (strndup(b1, sizeof(b1) != 0)) {} // \
+ expected-warning{{size argument in 'strndup' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strndup(b1, sizeof(b1)) != 0) {}
+
+ if (strlcpy(b1, b2, sizeof(b1) != 0)) {} // \
+ expected-warning{{size argument in 'strlcpy' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strlcpy(b1, b2, sizeof(b1)) != 0) {}
+
+ if (strlcat(b1, b2, sizeof(b1) != 0)) {} // \
+ expected-warning{{size argument in 'strlcat' call is a comparison}} \
+ expected-note {{did you mean to compare}} \
+ expected-note {{explicitly cast the argument}}
+ if (strlcat(b1, b2, sizeof(b1)) != 0) {}
+
+ if (memset(b1, 0, sizeof(b1) / 2)) {}
+ if (memset(b1, 0, sizeof(b1) >> 2)) {}
+ if (memset(b1, 0, 4 << 2)) {}
+ if (memset(b1, 0, 4 + 2)) {}
+ if (memset(b1, 0, 4 - 2)) {}
+ if (memset(b1, 0, 4 * 2)) {}
+
+ if (memset(b1, 0, (size_t)(sizeof(b1) != 0))) {}
+}
diff --git a/test/SemaCXX/warn-new-overaligned.cpp b/test/SemaCXX/warn-new-overaligned.cpp
index 42a4e35..710973c 100644
--- a/test/SemaCXX/warn-new-overaligned.cpp
+++ b/test/SemaCXX/warn-new-overaligned.cpp
@@ -38,7 +38,7 @@
} __attribute__((aligned(256)));
void* operator new(unsigned long) {
- return 0;
+ return 0; // expected-warning {{'operator new' should not return a null pointer unless it is declared 'throw()'}}
}
SeparateCacheLines<int> high_contention_data[10];
@@ -59,7 +59,7 @@
} __attribute__((aligned(256)));
void* operator new[](unsigned long) {
- return 0;
+ return 0; // expected-warning {{'operator new[]' should not return a null pointer unless it is declared 'throw()'}}
}
SeparateCacheLines<int> high_contention_data[10];
diff --git a/test/SemaCXX/warn-reinterpret-base-class.cpp b/test/SemaCXX/warn-reinterpret-base-class.cpp
index 36b8fda..0231f19 100644
--- a/test/SemaCXX/warn-reinterpret-base-class.cpp
+++ b/test/SemaCXX/warn-reinterpret-base-class.cpp
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
-// RUN: not %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -triple %itanium_abi_triple -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
+
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only -triple %itanium_abi_triple -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only -triple %ms_abi_triple -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
// PR 13824
class A {
@@ -288,6 +291,11 @@
(void)reinterpret_cast<I *>(f);
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
+#ifdef MSABI
+ // In MS ABI mode, A is at non-zero offset in H.
+ // expected-warning@+3 {{'reinterpret_cast' to class 'H *' from its base at non-zero offset 'A *' behaves differently from 'static_cast'}}
+ // expected-note@+2 {{use 'static_cast'}}
+#endif
(void)reinterpret_cast<H *>(a);
// expected-warning@+2 {{'reinterpret_cast' to class 'L' (aka 'const F *volatile') from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
@@ -309,6 +317,12 @@
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
(void)reinterpret_cast<E *>(h);
+
+#ifdef MSABI
+ // In MS ABI mode, A is at non-zero offset in H.
+ // expected-warning@+3 {{'reinterpret_cast' from class 'H *' to its base at non-zero offset 'A *' behaves differently from 'static_cast'}}
+ // expected-note@+2 {{use 'static_cast'}}
+#endif
(void)reinterpret_cast<A *>(h);
// expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'F *' behaves differently from 'static_cast'}}
diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp
index 68e9467..5ad2233 100644
--- a/test/SemaCXX/warn-shadow.cpp
+++ b/test/SemaCXX/warn-shadow.cpp
@@ -22,7 +22,7 @@
using namespace yy;
void foo() {
- int i; // expected-warning {{declaration shadows a variable in namespace '<anonymous>'}}
+ int i; // expected-warning {{declaration shadows a variable in namespace '(anonymous)'}}
int j; // expected-warning {{declaration shadows a variable in namespace 'one::two'}}
int m;
}
diff --git a/test/SemaCXX/warn-sign-conversion.cpp b/test/SemaCXX/warn-sign-conversion.cpp
index ba2bc9b..746b124 100644
--- a/test/SemaCXX/warn-sign-conversion.cpp
+++ b/test/SemaCXX/warn-sign-conversion.cpp
@@ -25,23 +25,23 @@
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 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'}}
+ 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'}}
}
}
diff --git a/test/SemaCXX/warn-string-conversion.cpp b/test/SemaCXX/warn-string-conversion.cpp
index 23960e4..b26126f 100644
--- a/test/SemaCXX/warn-string-conversion.cpp
+++ b/test/SemaCXX/warn-string-conversion.cpp
@@ -1,14 +1,20 @@
// 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.
+// An exception is made for this in logical and 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 || ""; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
+ b0 = "" || 0; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
b0 = 0 && "";
+ b0 = "" && 0;
assert("error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
+ assert(0 || "error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
+ assert("error" || 0); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
assert(0 && "error");
+ assert("error" && 0);
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'}}
diff --git a/test/SemaCXX/warn-sysheader-macro.cpp b/test/SemaCXX/warn-sysheader-macro.cpp
new file mode 100644
index 0000000..c884617
--- /dev/null
+++ b/test/SemaCXX/warn-sysheader-macro.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow -Wold-style-cast %s
+
+// Test that macro expansions from system headers don't trigger 'syntactic'
+// warnings that are not actionable.
+
+#ifdef IS_SYSHEADER
+#pragma clang system_header
+
+#define SANITY(a) (a / 0)
+
+#define SHADOW(a) __extension__({ int v = a; v; })
+
+#define OLD_STYLE_CAST(a) ((int) (a))
+
+#else
+
+#define IS_SYSHEADER
+#include __FILE__
+
+void testSanity() {
+ // Validate that the test is set up correctly
+ int i = SANITY(0); // expected-warning {{division by zero is undefined}}
+}
+
+void PR16093() {
+ // no -Wshadow in system macro expansion
+ int i = SHADOW(SHADOW(1));
+}
+
+void PR18147() {
+ // no -Wold_style_cast in system macro expansion
+ int i = OLD_STYLE_CAST(0);
+}
+
+#endif
diff --git a/test/SemaCXX/warn-tautological-compare.cpp b/test/SemaCXX/warn-tautological-compare.cpp
new file mode 100644
index 0000000..b44f3f9
--- /dev/null
+++ b/test/SemaCXX/warn-tautological-compare.cpp
@@ -0,0 +1,138 @@
+// Force x86-64 because some of our heuristics are actually based
+// on integer sizes.
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify -std=c++11 %s
+
+namespace RuntimeBehavior {
+ // Avoid emitting tautological compare warnings when the code already has
+ // compile time checks on variable sizes.
+
+ const int kintmax = 2147483647;
+ void test0(short x) {
+ if (sizeof(x) < sizeof(int) || x < kintmax) {}
+
+ if (x < kintmax) {}
+ // expected-warning@-1{{comparison of constant 2147483647 with expression of type 'short' is always true}}
+ }
+
+ void test1(short x) {
+ if (x < kintmax) {}
+ // expected-warning@-1{{comparison of constant 2147483647 with expression of type 'short' is always true}}
+
+ if (sizeof(x) < sizeof(int))
+ return;
+
+ if (x < kintmax) {}
+ }
+}
+
+namespace ArrayCompare {
+ #define GetValue(ptr) ((ptr != 0) ? ptr[0] : 0)
+ extern int a[] __attribute__((weak));
+ int b[] = {8,13,21};
+ struct {
+ int x[10];
+ } c;
+ const char str[] = "text";
+ void ignore() {
+ if (a == 0) {}
+ if (a != 0) {}
+ (void)GetValue(b);
+ }
+ void test() {
+ if (b == 0) {}
+ // expected-warning@-1{{comparison of array 'b' equal to a null pointer is always false}}
+ if (b != 0) {}
+ // expected-warning@-1{{comparison of array 'b' not equal to a null pointer is always true}}
+ if (0 == b) {}
+ // expected-warning@-1{{comparison of array 'b' equal to a null pointer is always false}}
+ if (0 != b) {}
+ // expected-warning@-1{{comparison of array 'b' not equal to a null pointer is always true}}
+ if (c.x == 0) {}
+ // expected-warning@-1{{comparison of array 'c.x' equal to a null pointer is always false}}
+ if (c.x != 0) {}
+ // expected-warning@-1{{comparison of array 'c.x' not equal to a null pointer is always true}}
+ if (str == 0) {}
+ // expected-warning@-1{{comparison of array 'str' equal to a null pointer is always false}}
+ if (str != 0) {}
+ // expected-warning@-1{{comparison of array 'str' not equal to a null pointer is always true}}
+ }
+}
+
+namespace FunctionCompare {
+ #define CallFunction(f) ((f != 0) ? f() : 0)
+ extern void a() __attribute__((weak));
+ void fun1();
+ int fun2();
+ int* fun3();
+ int* fun4(int);
+ class S {
+ public:
+ static int foo();
+ };
+ void ignore() {
+ if (a == 0) {}
+ if (0 != a) {}
+ (void)CallFunction(fun2);
+ }
+ void test() {
+ if (fun1 == 0) {}
+ // expected-warning@-1{{comparison of function 'fun1' equal to a null pointer is always false}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ if (fun2 == 0) {}
+ // expected-warning@-1{{comparison of function 'fun2' equal to a null pointer is always false}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+ if (fun3 == 0) {}
+ // expected-warning@-1{{comparison of function 'fun3' equal to a null pointer is always false}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+ if (fun4 == 0) {}
+ // expected-warning@-1{{comparison of function 'fun4' equal to a null pointer is always false}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ if (nullptr != fun1) {}
+ // expected-warning@-1{{comparison of function 'fun1' not equal to a null pointer is always true}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ if (nullptr != fun2) {}
+ // expected-warning@-1{{comparison of function 'fun2' not equal to a null pointer is always true}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ if (nullptr != fun3) {}
+ // expected-warning@-1{{comparison of function 'fun3' not equal to a null pointer is always true}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+ if (nullptr != fun4) {}
+ // expected-warning@-1{{comparison of function 'fun4' not equal to a null pointer is always true}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ if (S::foo == 0) {}
+ // expected-warning@-1{{comparison of function 'S::foo' equal to a null pointer is always false}}
+ // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+ // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+ }
+}
+
+namespace PointerCompare {
+ extern int a __attribute__((weak));
+ int b;
+ static int c;
+ class S {
+ public:
+ static int a;
+ int b;
+ };
+ void ignored() {
+ if (&a == 0) {}
+ }
+ void test() {
+ S s;
+ if (&b == 0) {}
+ // expected-warning@-1{{comparison of address of 'b' equal to a null pointer is always false}}
+ if (&c == 0) {}
+ // expected-warning@-1{{comparison of address of 'c' equal to a null pointer is always false}}
+ if (&s.a == 0) {}
+ // expected-warning@-1{{comparison of address of 's.a' equal to a null pointer is always false}}
+ if (&s.b == 0) {}
+ // expected-warning@-1{{comparison of address of 's.b' equal to a null pointer is always false}}
+ if (&S::a == 0) {}
+ // expected-warning@-1{{comparison of address of 'S::a' equal to a null pointer is always false}}
+ }
+}
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index ce6250d..34a33aa 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -208,33 +208,33 @@
void sls_fun_bad_1() {
sls_mu.Unlock(); // \
- // expected-warning{{unlocking 'sls_mu' that was not locked}}
+ // expected-warning{{releasing mutex 'sls_mu' that was not held}}
}
void sls_fun_bad_2() {
sls_mu.Lock();
sls_mu.Lock(); // \
- // expected-warning{{locking 'sls_mu' that is already locked}}
+ // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
sls_mu.Unlock();
}
void sls_fun_bad_3() {
sls_mu.Lock(); // expected-note {{mutex acquired here}}
-} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
void sls_fun_bad_4() {
if (getBool())
sls_mu.Lock(); // expected-note{{mutex acquired here}}
else
sls_mu2.Lock(); // expected-note{{mutex acquired here}}
-} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}} \
- // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}}
+} // expected-warning{{mutex 'sls_mu' is not held on every path through here}} \
+ // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
void sls_fun_bad_5() {
sls_mu.Lock(); // expected-note {{mutex acquired here}}
if (getBool())
sls_mu.Unlock();
-} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
+} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
void sls_fun_bad_6() {
if (getBool()) {
@@ -247,8 +247,8 @@
}
}
sls_mu.Unlock(); // \
- expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
- expected-warning{{unlocking 'sls_mu' that was not locked}}
+ expected-warning{{mutex 'sls_mu' is not held on every path through here}}\
+ expected-warning{{releasing mutex 'sls_mu' that was not held}}
}
void sls_fun_bad_7() {
@@ -258,7 +258,7 @@
if (getBool()) {
if (getBool()) {
continue; // \
- expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
}
}
sls_mu.Lock(); // expected-note {{mutex acquired here}}
@@ -270,14 +270,14 @@
sls_mu.Lock(); // expected-note{{mutex acquired here}}
do {
- sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
} while (getBool());
}
void sls_fun_bad_9() {
do {
sls_mu.Lock(); // \
- // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
+ // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
// expected-note{{mutex acquired here}}
} while (getBool());
sls_mu.Unlock();
@@ -285,18 +285,18 @@
void sls_fun_bad_10() {
sls_mu.Lock(); // expected-note 2{{mutex acquired here}}
- while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ while(getBool()) { // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
sls_mu.Unlock();
}
-} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
void sls_fun_bad_11() {
while (getBool()) { // \
- expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+ expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
sls_mu.Lock(); // expected-note {{mutex acquired here}}
}
sls_mu.Unlock(); // \
- // expected-warning{{unlocking 'sls_mu' that was not locked}}
+ // expected-warning{{releasing mutex 'sls_mu' that was not held}}
}
void sls_fun_bad_12() {
@@ -305,7 +305,7 @@
sls_mu.Unlock();
if (getBool()) {
if (getBool()) {
- break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
+ break; // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
}
}
sls_mu.Lock();
@@ -334,19 +334,19 @@
void aa_fun_bad_1() {
glock.globalUnlock(); // \
- // expected-warning{{unlocking 'aa_mu' that was not locked}}
+ // expected-warning{{releasing mutex 'aa_mu' that was not held}}
}
void aa_fun_bad_2() {
glock.globalLock();
glock.globalLock(); // \
- // expected-warning{{locking 'aa_mu' that is already locked}}
+ // expected-warning{{acquiring mutex 'aa_mu' that is already held}}
glock.globalUnlock();
}
void aa_fun_bad_3() {
glock.globalLock(); // expected-note{{mutex acquired here}}
-} // expected-warning{{mutex 'aa_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'aa_mu' is still held at the end of function}}
//--------------------------------------------------//
// Regression tests for unusual method names
@@ -359,17 +359,17 @@
// FIXME: can't currently check inside constructors and destructors.
WeirdMethods() {
wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
- } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
+ } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
~WeirdMethods() {
wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
- } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
+ } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
void operator++() {
wmu.Lock(); // expected-note {{mutex acquired here}}
- } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
+ } // expected-warning {{mutex 'wmu' is still held at the end of function}}
operator int*() {
wmu.Lock(); // expected-note {{mutex acquired here}}
return 0;
- } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
+ } // expected-warning {{mutex 'wmu' is still held at the end of function}}
};
//-----------------------------------------------//
@@ -386,13 +386,13 @@
__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}}
+ // expected-warning {{writing variable 'pgb_field' requires holding mutex 'sls_mu2' exclusively}}
+ *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
+ // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
+ x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
+ // expected-warning {{reading the value pointed to by 'pgb_field' requires holding mutex 'sls_mu'}}
+ (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
+ // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
}
};
@@ -402,7 +402,7 @@
void testFoo() {
gb_field = 0; // \
- // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
+ // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}
}
void testNoAnal() __attribute__((no_thread_safety_analysis)) {
@@ -435,59 +435,59 @@
void gb_bad_0() {
sls_guard_var = 1; // \
- // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
}
void gb_bad_1() {
int x = sls_guard_var; // \
- // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
+ // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}
}
void gb_bad_2() {
sls_guardby_var = 1; // \
- // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
+ // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}
}
void gb_bad_3() {
int x = sls_guardby_var; // \
- // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
+ // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}
}
void gb_bad_4() {
*pgb_gvar = 1; // \
- // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
+ // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding 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}}
+ // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}
}
void gb_bad_6() {
*pgb_var = 1; // \
- // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
+ // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex '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'}}
+ // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}
}
void gb_bad_8() {
GBFoo G;
G.gb_field = 0; // \
- // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
+ // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}
}
void gb_bad_9() {
sls_guard_var++; // \
- // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
sls_guard_var--; // \
- // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
++sls_guard_var; // \
- // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
--sls_guard_var;// \
- // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+ // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
}
//-----------------------------------------------//
@@ -503,11 +503,11 @@
void test() {
a = 0; // \
- // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+ // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}
b = a; // \
- // expected-warning {{reading variable 'a' requires locking 'mu'}}
+ // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
c = 0; // \
- // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
+ // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}
}
int c __attribute__((guarded_by(mu)));
@@ -549,7 +549,7 @@
LateFoo fooB;
fooA.mu.Lock();
fooB.a = 5; // \
- // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}} \
+ // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \
// expected-note{{found near match 'fooA.mu'}}
fooA.mu.Unlock();
}
@@ -560,7 +560,7 @@
b1.mu1_.Lock();
int res = b1.a_ + b3->b_;
b3->b_ = *b1.q; // \
- // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}}
+ // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}
b1.mu1_.Unlock();
b1.b_ = res;
mu.Unlock();
@@ -570,7 +570,7 @@
LateBar BarA;
BarA.FooPointer->mu.Lock();
BarA.Foo.a = 2; // \
- // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}} \
+ // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo.mu' exclusively}} \
// expected-note{{found near match 'BarA.FooPointer->mu'}}
BarA.FooPointer->mu.Unlock();
}
@@ -579,7 +579,7 @@
LateBar BarA;
BarA.Foo.mu.Lock();
BarA.FooPointer->a = 2; // \
- // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}} \
+ // expected-warning{{writing variable 'a' requires holding mutex 'BarA.FooPointer->mu' exclusively}} \
// expected-note{{found near match 'BarA.Foo.mu'}}
BarA.Foo.mu.Unlock();
}
@@ -588,7 +588,7 @@
LateBar BarA;
BarA.Foo.mu.Lock();
BarA.Foo2.a = 2; // \
- // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}} \
+ // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo2.mu' exclusively}} \
// expected-note{{found near match 'BarA.Foo.mu'}}
BarA.Foo.mu.Unlock();
}
@@ -608,11 +608,11 @@
void shared_fun_1() {
sls_mu.ReaderLock(); // \
- // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ // expected-warning {{mutex 'sls_mu' is acquired 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}}
+ // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
} while (getBool());
sls_mu.Unlock();
}
@@ -638,20 +638,20 @@
void shared_fun_8() {
if (getBool())
sls_mu.Lock(); // \
- // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
else
sls_mu.ReaderLock(); // \
- // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ // expected-note {{the other acquisition 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}}
+ // expected-warning {{mutex 'sls_mu' is acquired 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}}
+ // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
} while (getBool());
sls_mu.Unlock();
}
@@ -659,10 +659,10 @@
void shared_bad_1() {
if (getBool())
sls_mu.Lock(); // \
- // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
else
sls_mu.ReaderLock(); // \
- // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
*pgb_var = 1;
sls_mu.Unlock();
}
@@ -670,10 +670,10 @@
void shared_bad_2() {
if (getBool())
sls_mu.ReaderLock(); // \
- // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+ // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
else
sls_mu.Lock(); // \
- // expected-note {{the other lock of mutex 'sls_mu' is here}}
+ // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
*pgb_var = 1;
sls_mu.Unlock();
}
@@ -762,49 +762,49 @@
void es_bad_0() {
Bar.aa_elr_fun(); // \
- // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
+ // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
}
void es_bad_1() {
aa_mu.ReaderLock();
Bar.aa_elr_fun(); // \
- // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
+ // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
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'}}
+ // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}
}
void es_bad_3() {
MyLRFoo.test(); // \
- // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
+ // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
}
void es_bad_4() {
MyLRFoo.testShared(); // \
- // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
+ // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}
}
void es_bad_5() {
sls_mu.ReaderLock();
MyLRFoo.test(); // \
- // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
+ // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
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}}
+ // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
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}}
+ // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
sls_mu.Unlock();
}
@@ -1209,7 +1209,7 @@
{
int x;
mu_.Lock();
- x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
+ x = foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}
a_ = x + 1;
mu_.Unlock();
if (x > 5) {
@@ -1223,13 +1223,13 @@
{
Foo f1, *f2;
f1.mu_.Lock();
- f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}}
+ f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}
mu2.Lock();
f1.foo();
mu2.Unlock();
f1.mu_.Unlock();
f2->mu_.Lock();
- f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}}
+ f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}
f2->mu_.Unlock();
mu2.Lock();
w = 2;
@@ -1258,7 +1258,7 @@
b1->MyLock();
b1->a_ = 5;
b2->a_ = 3; // \
- // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}} \
+ // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \
// expected-note {{found near match 'b1->mu1_'}}
b2->MyLock();
b2->MyUnlock();
@@ -1288,18 +1288,18 @@
{
int x;
b3->mu1_.Lock();
- res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \
- // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} \
+ res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires holding mutex 'b1.mu1_'}} \
+ // expected-warning {{writing variable 'res' requires holding mutex 'mu' exclusively}} \
// expected-note {{found near match 'b3->mu1_'}}
- *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 'b1.mu1_' exclusively}} \
+ *p = i; // expected-warning {{reading variable 'p' requires holding mutex 'mu'}} \
+ // expected-warning {{writing the value pointed to by 'p' requires holding mutex 'mu' exclusively}}
+ b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}} \
+ // expected-warning {{writing variable 'a_' requires holding mutex 'b1.mu1_' exclusively}} \
// expected-note {{found near match 'b3->mu1_'}}
- b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
+ b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires holding mutex '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'}}
+ b1.b_ = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
+ x = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
return x;
}
} // end namespace thread_annot_lock_21
@@ -1321,10 +1321,10 @@
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 'child->lock_'}} \
+ // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \
// expected-note {{found near match 'lock_'}}
child->a_ = 5; // \
- // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}} \
+ // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \
// expected-note {{found near match 'lock_'}}
lock_.Unlock();
}
@@ -1362,7 +1362,7 @@
lock_.Lock();
child->lock_.Lock();
- child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}}
+ child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}
child->bar(7);
child->a_ = 5;
child->lock_.Unlock();
@@ -1401,8 +1401,8 @@
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}}
+ f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is held}} \
+ // expected-warning {{cannot call function 'f2' while mutex 'mu2' is held}}
}
};
@@ -1410,8 +1410,8 @@
void func()
{
- foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \
- // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}}
+ foo->f1(); // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu2' exclusively}} \
+ // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu1' exclusively}}
}
} // end namespace thread_annot_lock_42
@@ -1434,14 +1434,14 @@
Child *c;
Base *b = c;
- b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}}
+ b->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'b->mu_' exclusively}}
b->mu_.Lock();
- b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}}
+ b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is held}}
b->mu_.Unlock();
- c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}}
+ c->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}
c->mu_.Lock();
- c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}}
+ c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}
c->mu_.Unlock();
}
} // end namespace thread_annot_lock_46
@@ -1468,10 +1468,10 @@
void main()
{
Foo a;
- a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \
- // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
- // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \
- // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
+ a.method1(1); // expected-warning {{calling function 'method1' requires holding mutex 'a.mu1'}} \
+ // expected-warning {{calling function 'method1' requires holding mutex 'mu'}} \
+ // expected-warning {{calling function 'method1' requires holding mutex 'a.mu2'}} \
+ // expected-warning {{calling function 'method1' requires holding mutex 'mu3'}}
}
} // end namespace thread_annot_lock_67_modified
@@ -1516,14 +1516,14 @@
DataLocker dlr;
dlr.lockData(d1); // expected-note {{mutex acquired here}}
dlr.unlockData(d2); // \
- // expected-warning {{unlocking 'd2->mu' that was not locked}}
- } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}}
+ // expected-warning {{releasing mutex 'd2->mu' that was not held}}
+ } // expected-warning {{mutex 'd1->mu' is still held at the end of function}}
void bar4(MyData* d1, MyData* d2) {
DataLocker dlr;
dlr.lockData(d1);
foo(d2); // \
- // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}} \
+ // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \
// expected-note {{found near match 'd1->mu'}}
dlr.unlockData(d1);
}
@@ -1566,8 +1566,8 @@
template<typename U>
struct IndirectLock {
int DoNaughtyThings(T *t) {
- u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
- return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}}
+ u->n = 0; // expected-warning {{reading variable 'u' requires holding mutex 'm'}}
+ return t->s->n; // expected-warning {{reading variable 's' requires holding mutex 't->m'}}
}
};
@@ -1583,7 +1583,7 @@
template<typename U> struct W {
V v;
void f(U u) {
- v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}}
+ v.p->f(u); // expected-warning {{reading variable 'p' requires holding mutex 'v.m'}}
}
};
template struct W<int>; // expected-note {{here}}
@@ -1620,7 +1620,7 @@
void foo3() {
MutexLock mulock_a(&mu1);
MutexLock mulock_b(&mu1); // \
- // expected-warning {{locking 'mu1' that is already locked}}
+ // expected-warning {{acquiring mutex 'mu1' that is already held}}
}
void foo4() {
@@ -1646,7 +1646,7 @@
void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
void bar() {
- foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}}
+ foo(); // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}
fooObj.mu_.Lock();
foo();
fooObj.mu_.Unlock();
@@ -1722,7 +1722,7 @@
if (cond)
b = true;
if (b) { // b should be unknown at this point, because of the join point
- a = 8; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
+ a = 8; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
}
if (b2) { // b2 should be known at this point.
a = 8;
@@ -1748,7 +1748,7 @@
while (cond) {
if (b) { // b should be uknown at this point b/c of the loop
- a = 10; // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
+ a = 10; // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
}
b = !b;
}
@@ -1876,7 +1876,7 @@
f1.mu_.Unlock();
bt.barTD(&f1); // \
- // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}} \
+ // expected-warning {{calling function 'barTD' requires holding mutex 'f1.mu_' exclusively}} \
// expected-note {{found near match 'bt.fooBase.mu_'}}
bt.fooBase.mu_.Unlock();
@@ -1885,7 +1885,7 @@
Cell<int> cell;
cell.data = 0; // \
- // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}}
+ // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}
cell.foo();
cell.mu_.Lock();
cell.fooEx();
@@ -1954,7 +1954,7 @@
void test() {
Foo myfoo;
myfoo.foo1(&myfoo); // \
- // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}}
+ // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}
myfoo.mu_.Lock();
myfoo.foo1(&myfoo);
myfoo.mu_.Unlock();
@@ -1980,7 +1980,7 @@
if (bar()) {
// ...
if (foo())
- continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
+ continue; // expected-warning {{expecting mutex 'm' to be held at start of each loop}}
//...
}
// ...
@@ -2069,21 +2069,21 @@
Foo myFoo;
myFoo.foo2(); // \
- // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'foo2' requires holding mutex 'myFoo.mu_' exclusively}}
myFoo.foo3(&myFoo); // \
- // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'foo3' requires holding mutex 'myFoo.mu_' exclusively}}
myFoo.fooT1(dummy); // \
- // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'fooT1' requires holding mutex 'myFoo.mu_' exclusively}}
myFoo.fooT2(dummy); // \
- // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'fooT2' requires holding mutex 'myFoo.mu_' exclusively}}
fooF1(&myFoo); // \
- // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}
fooF2(&myFoo); // \
- // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}
fooF3(&myFoo); // \
- // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}}
+ // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}
myFoo.mu_.Lock();
myFoo.foo2();
@@ -2099,7 +2099,7 @@
FooT<int> myFooT;
myFooT.foo(); // \
- // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}}
+ // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}
}
} // end namespace FunctionDefinitionTest
@@ -2127,7 +2127,7 @@
void test() {
foo = 2; // \
- // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
+ // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}
}
};
@@ -2192,11 +2192,11 @@
void foo() {
a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
b = 0; // \
- // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
c = 0; // \
- // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
}
private:
@@ -2283,31 +2283,31 @@
bar.getFoo().mu_.Lock();
bar.getFooey().a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}} \
+ // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFooey().mu_' exclusively}} \
// expected-note {{found near match 'bar.getFoo().mu_'}}
bar.getFoo().mu_.Unlock();
bar.getFoo2(a).mu_.Lock();
bar.getFoo2(b).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}} \
+ // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo2(b).mu_' exclusively}} \
// expected-note {{found near match 'bar.getFoo2(a).mu_'}}
bar.getFoo2(a).mu_.Unlock();
bar.getFoo3(a, b).mu_.Lock();
bar.getFoo3(a, c).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}} \
+ // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo3(a,c).mu_' exclusively}} \
// expected-note {{'bar.getFoo3(a,b).mu_'}}
bar.getFoo3(a, b).mu_.Unlock();
getBarFoo(bar, a).mu_.Lock();
getBarFoo(bar, b).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}} \
+ // expected-warning {{writing variable 'a' requires holding mutex 'getBarFoo(bar,b).mu_' exclusively}} \
// expected-note {{'getBarFoo(bar,a).mu_'}}
getBarFoo(bar, a).mu_.Unlock();
(a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
(a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
- // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}} \
+ // expected-warning {{writing variable 'a' requires holding mutex '((a#_)#_#fooArray[b]).mu_' exclusively}} \
// expected-note {{'((a#_)#_#fooArray[_]).mu_'}}
(a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
}
@@ -2356,19 +2356,19 @@
// Calls getMu() directly to lock and unlock
void test1(Foo* f1, Foo* f2) {
- f1->a = 0; // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}}
- f1->foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}}
+ f1->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'f1->mu_' exclusively}}
+ f1->foo(); // expected-warning {{calling function 'foo' requires holding mutex 'f1->mu_' exclusively}}
- f1->foo2(f2); // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \
- // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
- Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}}
+ f1->foo2(f2); // expected-warning {{calling function 'foo2' requires holding mutex 'f1->mu_' exclusively}} \
+ // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}}
+ Foo::sfoo(f1); // expected-warning {{calling function 'sfoo' requires holding mutex 'f1->mu_' exclusively}}
f1->getMu()->Lock();
f1->a = 0;
f1->foo();
f1->foo2(f2); // \
- // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}} \
+ // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}} \
// expected-note {{found near match 'f1->mu_'}}
Foo::getMu(f2)->Lock();
@@ -2398,19 +2398,19 @@
// Use getMu() within other attributes.
// This requires at lest levels of substitution, more in the case of
void test2(Bar* b1, Bar* b2) {
- b1->b = 0; // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}}
- b1->bar(); // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}}
- b1->bar2(b2); // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \
- // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
- Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}}
- Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}}
+ b1->b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'b1->mu_' exclusively}}
+ b1->bar(); // expected-warning {{calling function 'bar' requires holding mutex 'b1->mu_' exclusively}}
+ b1->bar2(b2); // expected-warning {{calling function 'bar2' requires holding mutex 'b1->mu_' exclusively}} \
+ // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}}
+ Bar::sbar(b1); // expected-warning {{calling function 'sbar' requires holding mutex 'b1->mu_' exclusively}}
+ Bar::sbar2(b1); // expected-warning {{calling function 'sbar2' requires holding mutex 'b1->mu_' exclusively}}
b1->getMu()->Lock();
b1->b = 0;
b1->bar();
b1->bar2(b2); // \
- // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}} \
+ // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \
// // expected-note {{found near match 'b1->mu_'}}
b2->getMu()->Lock();
@@ -2476,13 +2476,13 @@
ReleasableMutexLock rlock(&mu_);
a = 0;
rlock.Release();
- a = 1; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 1; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
}
void Foo::test4() {
ReleasableMutexLock rlock(&mu_);
rlock.Release();
- rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}}
+ rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
}
void Foo::test5() {
@@ -2491,7 +2491,7 @@
rlock.Release();
}
// no warning on join point for managed lock.
- rlock.Release(); // expected-warning {{unlocking 'mu_' that was not locked}}
+ rlock.Release(); // expected-warning {{releasing mutex 'mu_' that was not held}}
}
@@ -2560,12 +2560,12 @@
void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
mutex_.Unlock();
- } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}}
mutex_.Unlock();
- } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
};
} // end namespace UnlockBug
@@ -2599,7 +2599,7 @@
void test2() {
WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
- } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+ } // expected-warning {{mutex 'mu_' is still held at the end of function}}
void test3() {
if (c) {
@@ -2622,7 +2622,7 @@
if (c) {
WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
}
- } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
+ } // expected-warning {{mutex 'mu_' is not held on every path through here}}
void test6() {
if (c) {
@@ -2631,7 +2631,7 @@
else {
WTF_ScopedLockable wtf(&mu_); // expected-note {{mutex acquired here}}
}
- } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
+ } // expected-warning {{mutex 'mu_' is not held on every path through here}}
};
@@ -2655,7 +2655,7 @@
ReaderMutexLock lock(getMutexPtr().get());
int b = a;
}
- int b = a; // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}}
+ int b = a; // expected-warning {{reading variable 'a' requires holding mutex 'getMutexPtr()'}}
}
} // end namespace TemporaryCleanupExpr
@@ -2686,9 +2686,9 @@
};
void Foo::test0() {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
- b = 0; // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
- c = 0; // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
+ b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
+ c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
}
void Foo::test1() {
@@ -2772,10 +2772,10 @@
void Foo::test8() {
mu_->Lock();
- mu_.get()->Lock(); // expected-warning {{locking 'mu_' that is already locked}}
- (*mu_).Lock(); // expected-warning {{locking 'mu_' that is already locked}}
+ mu_.get()->Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
+ (*mu_).Lock(); // expected-warning {{acquiring mutex 'mu_' that is already held}}
mu_.get()->Unlock();
- Unlock(); // expected-warning {{unlocking 'mu_' that was not locked}}
+ Unlock(); // expected-warning {{releasing mutex 'mu_' that was not held}}
}
@@ -2790,9 +2790,9 @@
void Bar::test0() {
- foo->a = 0; // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}}
- (*foo).b = 0; // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}}
- foo.get()->c = 0; // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}}
+ foo->a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
+ (*foo).b = 0; // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
+ foo.get()->c = 0; // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
}
@@ -2906,9 +2906,9 @@
foo.unlock();
foo.lock();
- foo.lock(); // expected-warning {{locking 'foo' that is already locked}}
+ foo.lock(); // expected-warning {{acquiring mutex 'foo' that is already held}}
foo.unlock();
- foo.unlock(); // expected-warning {{unlocking 'foo' that was not locked}}
+ foo.unlock(); // expected-warning {{releasing mutex 'foo' that was not held}}
}
@@ -2919,10 +2919,10 @@
foo.unlock1();
foo.lock1();
- foo.lock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}}
+ foo.lock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
foo.a = 0;
foo.unlock1();
- foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
+ foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
}
@@ -2933,10 +2933,10 @@
foo.unlock1();
foo.slock1();
- foo.slock1(); // expected-warning {{locking 'foo.mu1_' that is already locked}}
+ foo.slock1(); // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
int d2 = foo.a;
foo.unlock1();
- foo.unlock1(); // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
+ foo.unlock1(); // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
return d1 + d2;
}
@@ -2951,17 +2951,17 @@
foo.lock3();
foo.lock3(); // \
- // expected-warning {{locking 'foo.mu1_' that is already locked}} \
- // expected-warning {{locking 'foo.mu2_' that is already locked}} \
- // expected-warning {{locking 'foo.mu3_' that is already locked}}
+ // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
+ // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
+ // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
foo.a = 0;
foo.b = 0;
foo.c = 0;
foo.unlock3();
foo.unlock3(); // \
- // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
- // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
- // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
+ // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
+ // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
+ // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
}
@@ -2975,17 +2975,17 @@
foo.locklots();
foo.locklots(); // \
- // expected-warning {{locking 'foo.mu1_' that is already locked}} \
- // expected-warning {{locking 'foo.mu2_' that is already locked}} \
- // expected-warning {{locking 'foo.mu3_' that is already locked}}
+ // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
+ // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
+ // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
foo.a = 0;
foo.b = 0;
foo.c = 0;
foo.unlocklots();
foo.unlocklots(); // \
- // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
- // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
- // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
+ // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
+ // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
+ // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
}
} // end namespace DuplicateAttributeTest
@@ -3010,7 +3010,7 @@
void Foo::test1() {
if (tryLockMutexP() == 0) {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
return;
}
a = 0;
@@ -3032,14 +3032,14 @@
}
if (tryLockMutexI() == 0) {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
return;
}
a = 0;
unlock();
if (0 == tryLockMutexI()) {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
return;
}
a = 0;
@@ -3051,7 +3051,7 @@
}
if (mu_.TryLock() == false) {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
return;
}
a = 0;
@@ -3062,12 +3062,12 @@
unlock();
}
else {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
}
#if __has_feature(cxx_nullptr)
if (tryLockMutexP() == nullptr) {
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
return;
}
a = 0;
@@ -3103,26 +3103,26 @@
Graph g2;
Node n1;
- n1.a = 0; // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}}
- n1.foo(); // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}}
+ n1.a = 0; // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
+ n1.foo(); // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
n1.foo2();
g1.mu_.Lock();
n1.a = 0;
n1.foo();
- n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+ n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
g1.mu_.Unlock();
g2.mu_.Lock();
n1.a = 0;
n1.foo();
- n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+ n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
g2.mu_.Unlock();
LockAllGraphs();
n1.a = 0;
n1.foo();
- n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+ n1.foo2(); // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
UnlockAllGraphs();
LockAllGraphs();
@@ -3132,7 +3132,7 @@
g2.mu_.Unlock();
LockAllGraphs();
- g1.mu_.Lock(); // expected-warning {{locking 'g1.mu_' that is already locked}}
+ g1.mu_.Lock(); // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
g1.mu_.Unlock();
}
@@ -3260,9 +3260,9 @@
beginNoWarnOnWrites();
}
a = 0; // \
- // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
endNoWarnOnWrites(); // \
- // expected-warning {{unlocking '*' that was not locked}}
+ // expected-warning {{releasing mutex '*' that was not held}}
}
@@ -3390,17 +3390,17 @@
void test1() {
- Foo f; // expected-warning {{calling function 'Foo' requires exclusive lock on 'mu_'}}
- int a = f[0]; // expected-warning {{calling function 'operator[]' requires exclusive lock on 'mu_'}}
-} // expected-warning {{calling function '~Foo' requires exclusive lock on 'mu_'}}
+ Foo f; // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}
+ int a = f[0]; // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}
+} // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}
void test2() {
Bar::mu_.Lock();
{
- Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is locked}}
- int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is locked}}
- } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is locked}}
+ Bar b; // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}
+ int a = b[0]; // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}
+ } // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}
Bar::mu_.Unlock();
}
@@ -3499,7 +3499,7 @@
void Foo::test() {
Cell<int> cell;
elr(&cell); // \
- // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
+ // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
}
@@ -3512,7 +3512,7 @@
void globalTest() {
Cell<int> cell;
globalELR(&cell); // \
- // expected-warning {{calling function 'globalELR' requires exclusive lock on 'cell.mu_'}}
+ // expected-warning {{calling function 'globalELR' requires holding mutex 'cell.mu_' exclusively}}
}
@@ -3533,7 +3533,7 @@
void globalTest2() {
Cell<int> cell;
globalELR2(&cell); // \
- // expected-warning {{calling function 'globalELR2' requires exclusive lock on 'cell.mu_'}}
+ // expected-warning {{calling function 'globalELR2' requires holding mutex 'cell.mu_' exclusively}}
}
@@ -3550,7 +3550,7 @@
Cell<int> cell;
FooT<int> foo;
foo.elr(&cell); // \
- // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
+ // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
}
} // end namespace TemplateFunctionParamRemapTest
@@ -3616,8 +3616,14 @@
EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
SHARED_TRYLOCK_FUNCTION(true, mu2_);
+ void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
+ ASSERT_EXCLUSIVE_LOCK(mu2_);
+ void assertShared() ASSERT_SHARED_LOCK(mu1_)
+ ASSERT_SHARED_LOCK(mu2_);
void test();
+ void testAssert();
+ void testAssertShared();
};
@@ -3676,6 +3682,21 @@
}
}
+// Force duplication of attributes
+void Foo::assertBoth() { }
+void Foo::assertShared() { }
+
+void Foo::testAssert() {
+ assertBoth();
+ a = 0;
+ b = 0;
+}
+
+void Foo::testAssertShared() {
+ assertShared();
+ int zz = a + b;
+}
+
} // end namespace MultipleAttributeTest
@@ -3717,24 +3738,24 @@
// method call tests
void test() {
data_.setValue(0); // FIXME -- should be writing \
- // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+ // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
int a = data_.getValue(); // \
- // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+ // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
datap1_->setValue(0); // FIXME -- should be writing \
- // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
+ // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
a = datap1_->getValue(); // \
- // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
+ // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
datap2_->setValue(0); // FIXME -- should be writing \
- // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
a = datap2_->getValue(); // \
- // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
(*datap2_).setValue(0); // FIXME -- should be writing \
- // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
a = (*datap2_).getValue(); // \
- // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
mu_.Lock();
data_.setValue(1);
@@ -3752,31 +3773,31 @@
// operator tests
void test2() {
- data_ = Data(1); // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}}
- *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} \
- // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
- *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires locking 'mu_' exclusively}} \
- // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
- data_ = *datap1_; // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
- // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
- data_ = *datap2_; // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
- // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ data_ = Data(1); // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
+ *datap1_ = data_; // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \
+ // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+ *datap2_ = data_; // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \
+ // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+ data_ = *datap1_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
+ // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
+ data_ = *datap2_; // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
+ // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
- data_[0] = 0; // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
- (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ data_[0] = 0; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+ (*datap2_)[0] = 0; // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
- data_(); // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+ data_(); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
}
// const operator tests
void test3() const {
- Data mydat(data_); // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+ Data mydat(data_); // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
//FIXME
- //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires locking 'mu_'}}
- //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+ //showDataCell(data_); // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+ //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
- int a = data_[0]; // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+ int a = data_[0]; // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
}
private:
@@ -3820,31 +3841,31 @@
Foo* foop PT_GUARDED_BY(mu_);
void test() {
- foo.myMethod(); // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
+ foo.myMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
- int fa = foo.a; // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
- foo.a = fa; // expected-warning {{writing variable 'foo' requires locking 'mu_' exclusively}}
+ int fa = foo.a; // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
+ foo.a = fa; // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}
- fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
- foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
+ fa = foop->a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
+ foop->a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
- fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
- (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
+ fa = (*foop).a; // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
+ (*foop).a = fa; // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
- foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires locking 'mu_'}} \
- // expected-warning {{writing variable 'c' requires locking 'foo.cell_mu_' exclusively}}
- foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires locking 'mu_'}} \
- // expected-warning {{reading variable 'c' requires locking 'foo.cell_mu_'}}
+ foo.c = Cell(0); // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \
+ // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}
+ foo.c.cellMethod(); // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \
+ // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}
- foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
- // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
- foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
- // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
+ foop->c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+ // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
+ foop->c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+ // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
- (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
- // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
- (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
- // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
+ (*foop).c = Cell(0); // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+ // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
+ (*foop).c.cellMethod(); // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+ // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
};
};
@@ -3917,34 +3938,34 @@
void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
mu2_.Lock();
mu2_.Unlock();
- } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
void readerLockBad() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
mu2_.Lock();
mu2_.Unlock();
- } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
void unlockBad() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
mu2_.Lock();
mu2_.Unlock();
- } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+ } // expected-warning {{mutex 'mu_' is still held at the end of function}}
// Check locking the wrong thing.
void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
mu2_.Lock(); // expected-note {{mutex acquired here}}
- } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
- // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
+ // expected-warning {{mutex 'mu2_' is still held at the end of function}}
void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
mu2_.ReaderLock(); // expected-note {{mutex acquired here}}
- } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
- // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
+ } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
+ // expected-warning {{mutex 'mu2_' is still held at the end of function}}
void unlockBad2() UNLOCK_FUNCTION(mu_) { // expected-note {{mutex acquired here}}
- mu2_.Unlock(); // expected-warning {{unlocking 'mu2_' that was not locked}}
- } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+ mu2_.Unlock(); // expected-warning {{releasing mutex 'mu2_' that was not held}}
+ } // expected-warning {{mutex 'mu_' is still held at the end of function}}
private:
Mutex mu_;
@@ -3971,7 +3992,7 @@
void test2() {
mu_.AssertReaderHeld();
int b = a;
- a = 0; // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+ a = 0; // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
}
void test3() {
@@ -4032,7 +4053,7 @@
else {
mu_.Lock(); // expected-note {{mutex acquired here}}
}
- } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+ } // expected-warning {{mutex 'mu_' is still held at the end of function}}
void test10() {
if (c) {
@@ -4041,7 +4062,7 @@
else {
mu_.AssertHeld();
}
- } // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+ } // expected-warning {{mutex 'mu_' is still held at the end of function}}
void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
@@ -4178,52 +4199,52 @@
void test2() {
mu1.ReaderLock();
- if (*a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires locking 'mu2'}}
- *a = 0; // expected-warning {{writing the value pointed to by 'a' requires locking 'mu2' exclusively}}
+ if (*a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
+ *a = 0; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
- if (c->a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}}
- c->a = 0; // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}}
+ if (c->a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
+ c->a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
- if ((*c).a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}}
- (*c).a = 0; // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}}
+ if ((*c).a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
+ (*c).a = 0; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
- if (a[0] == 42) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires locking 'mu2'}}
- a[0] = 57; // expected-warning {{writing the value pointed to by 'a' requires locking 'mu2' exclusively}}
- if (c[0].a == 42) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}}
- c[0].a = 57; // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}}
+ if (a[0] == 42) doSomething(); // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
+ a[0] = 57; // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
+ if (c[0].a == 42) doSomething(); // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
+ c[0].a = 57; // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
mu1.Unlock();
}
void test3() {
mu2.Lock();
- if (*a == 0) doSomething(); // expected-warning {{reading variable 'a' requires locking 'mu1'}}
- *a = 0; // expected-warning {{reading variable 'a' requires locking 'mu1'}}
+ if (*a == 0) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
+ *a = 0; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
- if (c->a == 0) doSomething(); // expected-warning {{reading variable 'c' requires locking 'mu1'}}
- c->a = 0; // expected-warning {{reading variable 'c' requires locking 'mu1'}}
+ if (c->a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
+ c->a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
- if ((*c).a == 0) doSomething(); // expected-warning {{reading variable 'c' requires locking 'mu1'}}
- (*c).a = 0; // expected-warning {{reading variable 'c' requires locking 'mu1'}}
+ if ((*c).a == 0) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
+ (*c).a = 0; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
- if (a[0] == 42) doSomething(); // expected-warning {{reading variable 'a' requires locking 'mu1'}}
- a[0] = 57; // expected-warning {{reading variable 'a' requires locking 'mu1'}}
- if (c[0].a == 42) doSomething(); // expected-warning {{reading variable 'c' requires locking 'mu1'}}
- c[0].a = 57; // expected-warning {{reading variable 'c' requires locking 'mu1'}}
+ if (a[0] == 42) doSomething(); // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
+ a[0] = 57; // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
+ if (c[0].a == 42) doSomething(); // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
+ c[0].a = 57; // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
mu2.Unlock();
}
void test4() { // Literal arrays
- if (sa[0] == 42) doSomething(); // expected-warning {{reading variable 'sa' requires locking 'mu1'}}
- sa[0] = 57; // expected-warning {{writing variable 'sa' requires locking 'mu1' exclusively}}
- if (sc[0].a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires locking 'mu1'}}
- sc[0].a = 57; // expected-warning {{writing variable 'sc' requires locking 'mu1' exclusively}}
+ if (sa[0] == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
+ sa[0] = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
+ if (sc[0].a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
+ sc[0].a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
- if (*sa == 42) doSomething(); // expected-warning {{reading variable 'sa' requires locking 'mu1'}}
- *sa = 57; // expected-warning {{writing variable 'sa' requires locking 'mu1' exclusively}}
- if ((*sc).a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires locking 'mu1'}}
- (*sc).a = 57; // expected-warning {{writing variable 'sc' requires locking 'mu1' exclusively}}
- if (sc->a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires locking 'mu1'}}
- sc->a = 57; // expected-warning {{writing variable 'sc' requires locking 'mu1' exclusively}}
+ if (*sa == 42) doSomething(); // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
+ *sa = 57; // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
+ if ((*sc).a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
+ (*sc).a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
+ if (sc->a == 42) doSomething(); // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
+ sc->a = 57; // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
}
void test5() {
@@ -4268,15 +4289,15 @@
void test2() {
mu2.Lock();
- sp.get(); // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
- if (*sp == 0) doSomething(); // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
- *sp = 0; // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
- sq->a = 0; // expected-warning {{reading variable 'sq' requires locking 'mu1'}}
+ sp.get(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+ if (*sp == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+ *sp = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+ sq->a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
- if (sp[0] == 0) doSomething(); // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
- sp[0] = 0; // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
- if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires locking 'mu1'}}
- sq[0].a = 0; // expected-warning {{reading variable 'sq' requires locking 'mu1'}}
+ if (sp[0] == 0) doSomething(); // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+ sp[0] = 0; // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+ if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
+ sq[0].a = 0; // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
mu2.Unlock();
}
@@ -4285,14 +4306,14 @@
mu1.Lock();
sp.get();
- if (*sp == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
- *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
- sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}}
+ if (*sp == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+ *sp = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+ sq->a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
- if (sp[0] == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
- sp[0] = 0; // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
- if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}}
- sq[0].a = 0; // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}}
+ if (sp[0] == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+ sp[0] = 0; // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+ if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
+ sq[0].a = 0; // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
mu1.Unlock();
}
@@ -4305,7 +4326,7 @@
class A {
void Run() {
- (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires exclusive lock on 'M'}}
+ (RunHelper)(); // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
}
void RunHelper() __attribute__((exclusive_locks_required(M)));
@@ -4314,3 +4335,46 @@
} // end namespace NonMemberCalleeICETest
+
+namespace pt_guard_attribute_type {
+ int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
+ int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
+
+ void test() {
+ int i PT_GUARDED_BY(sls_mu); // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+ int j PT_GUARDED_VAR; // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+
+ typedef int PT_GUARDED_BY(sls_mu) bad1; // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+ typedef int PT_GUARDED_VAR bad2; // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+ }
+} // end namespace pt_guard_attribute_type
+
+
+namespace ThreadAttributesOnLambdas {
+
+class Foo {
+ Mutex mu_;
+
+ void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+
+ void test() {
+ auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
+ LockedFunction();
+ };
+
+ auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS {
+ LockedFunction();
+ };
+
+ auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) {
+ mu_.Lock();
+ };
+
+ func1(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
+ func2();
+ func3();
+ mu_.Unlock();
+ }
+};
+
+} // end namespace ThreadAttributesOnLambdas
diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp
index 1bd4e43..6d4ad39 100644
--- a/test/SemaCXX/warn-thread-safety-parsing.cpp
+++ b/test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -229,28 +229,28 @@
};
void l_test_function() LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
int l_testfn(int y) {
int x LOCKABLE = y; // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
return x;
}
int l_test_var LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
class LFoo {
private:
int test_field LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
void test_method() LOCKABLE; // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
};
void l_function_params(int lvar LOCKABLE); // \
- // expected-warning {{'lockable' attribute only applies to classes}}
+ // expected-warning {{'lockable' attribute only applies to struct, union or class}}
//-----------------------------------------//
@@ -269,28 +269,28 @@
};
void sl_test_function() SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
int sl_testfn(int y) {
int x SCOPED_LOCKABLE = y; // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
return x;
}
int sl_test_var SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
class SLFoo {
private:
int test_field SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
void test_method() SCOPED_LOCKABLE; // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
};
void sl_function_params(int lvar SCOPED_LOCKABLE); // \
- // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+ // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
//-----------------------------------------//
@@ -353,13 +353,13 @@
// illegal attribute arguments
int gb_var_arg_bad_1 GUARDED_BY(1); // \
- // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'int'}}
+ // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int gb_var_arg_bad_2 GUARDED_BY("mu"); // \
// expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
int gb_var_arg_bad_3 GUARDED_BY(muDoublePointer); // \
- // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'class Mutex **'}}
+ // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int gb_var_arg_bad_4 GUARDED_BY(umu); // \
- // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class UnlockableMu'}}
+ // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'UnlockableMu'}}
//3.
// Thread Safety analysis tests
@@ -424,13 +424,13 @@
// illegal attribute arguments
int * pgb_var_arg_bad_1 PT_GUARDED_BY(1); // \
- // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int * pgb_var_arg_bad_2 PT_GUARDED_BY("mu"); // \
// expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}}
int * pgb_var_arg_bad_3 PT_GUARDED_BY(muDoublePointer); // \
- // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int * pgb_var_arg_bad_4 PT_GUARDED_BY(umu); // \
- // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute}}
//-----------------------------------------//
@@ -446,12 +446,12 @@
Mutex mu_aa ACQUIRED_AFTER(mu1);
Mutex aa_var_noargs __attribute__((acquired_after)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'acquired_after' attribute takes at least 1 argument}}
class AAFoo {
private:
Mutex aa_field_noargs __attribute__((acquired_after)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'acquired_after' attribute takes at least 1 argument}}
Mutex aa_field_args ACQUIRED_AFTER(mu1);
};
@@ -485,15 +485,15 @@
// illegal attribute arguments
Mutex aa_var_arg_bad_1 ACQUIRED_AFTER(1); // \
- // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \
// expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}}
Mutex aa_var_arg_bad_3 ACQUIRED_AFTER(muDoublePointer); // \
- // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \
- // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute}}
UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER(mu_aa); // \
- // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'lockable' attribute}}
+ // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'capability("mutex")' attribute}}
//-----------------------------------------//
// Acquired Before (ab)
@@ -506,12 +506,12 @@
Mutex mu_ab ACQUIRED_BEFORE(mu1);
Mutex ab_var_noargs __attribute__((acquired_before)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'acquired_before' attribute takes at least 1 argument}}
class ABFoo {
private:
Mutex ab_field_noargs __attribute__((acquired_before)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'acquired_before' attribute takes at least 1 argument}}
Mutex ab_field_args ACQUIRED_BEFORE(mu1);
};
@@ -548,15 +548,15 @@
// illegal attribute arguments
Mutex ab_var_arg_bad_1 ACQUIRED_BEFORE(1); // \
- // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \
// expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}}
Mutex ab_var_arg_bad_3 ACQUIRED_BEFORE(muDoublePointer); // \
- // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \
- // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute}}
UnlockableMu ab_var_arg_bad_5 ACQUIRED_BEFORE(mu_ab); // \
- // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'lockable' attribute}}
+ // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'capability("mutex")' attribute}}
//-----------------------------------------//
@@ -617,9 +617,9 @@
int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \
// expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}}
int elf_function_bad_3() EXCLUSIVE_LOCK_FUNCTION(muDoublePointer); // \
- // expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int elf_function_bad_4() EXCLUSIVE_LOCK_FUNCTION(umu); // \
- // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
int elf_function_bad_1() EXCLUSIVE_LOCK_FUNCTION(1); // \
// expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -689,9 +689,9 @@
int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \
// expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}}
int slf_function_bad_3() SHARED_LOCK_FUNCTION(muDoublePointer); // \
- // expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int slf_function_bad_4() SHARED_LOCK_FUNCTION(umu); // \
- // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
int slf_function_bad_1() SHARED_LOCK_FUNCTION(1); // \
// expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -715,7 +715,7 @@
// plus an optional list of locks (vars/fields)
void etf_function() __attribute__((exclusive_trylock_function)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'exclusive_trylock_function' attribute takes at least 1 argument}}
void etf_function_args() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu2);
@@ -771,9 +771,9 @@
int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \
// expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}
int etf_function_bad_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoublePointer); // \
- // expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int etf_function_bad_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, umu); // \
- // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
//-----------------------------------------//
@@ -788,7 +788,7 @@
// plus an optional list of locks (vars/fields)
void stf_function() __attribute__((shared_trylock_function)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'shared_trylock_function' attribute takes at least 1 argument}}
void stf_function_args() SHARED_TRYLOCK_FUNCTION(1, mu2);
@@ -845,9 +845,9 @@
int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \
// expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}
int stf_function_bad_5() SHARED_TRYLOCK_FUNCTION(1, muDoublePointer); // \
- // expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int stf_function_bad_6() SHARED_TRYLOCK_FUNCTION(1, umu); // \
- // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
//-----------------------------------------//
@@ -908,9 +908,9 @@
int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \
// expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}}
int uf_function_bad_3() UNLOCK_FUNCTION(muDoublePointer); // \
- // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int uf_function_bad_4() UNLOCK_FUNCTION(umu); // \
- // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
int uf_function_bad_1() UNLOCK_FUNCTION(1); // \
// expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -980,13 +980,13 @@
// illegal attribute arguments
int lr_function_bad_1() LOCK_RETURNED(1); // \
- // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int lr_function_bad_2() LOCK_RETURNED("mu"); // \
// expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}}
int lr_function_bad_3() LOCK_RETURNED(muDoublePointer); // \
- // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int lr_function_bad_4() LOCK_RETURNED(umu); // \
- // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute}}
@@ -1001,7 +1001,7 @@
// takes one or more arguments, all locks (vars/fields)
void le_function() __attribute__((locks_excluded)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'locks_excluded' attribute takes at least 1 argument}}
void le_function_arg() LOCKS_EXCLUDED(mu1);
@@ -1047,13 +1047,13 @@
// illegal attribute arguments
int le_function_bad_1() LOCKS_EXCLUDED(1); // \
- // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int le_function_bad_2() LOCKS_EXCLUDED("mu"); // \
// expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}}
int le_function_bad_3() LOCKS_EXCLUDED(muDoublePointer); // \
- // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int le_function_bad_4() LOCKS_EXCLUDED(umu); // \
- // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute}}
@@ -1068,7 +1068,7 @@
// takes one or more arguments, all locks (vars/fields)
void elr_function() __attribute__((exclusive_locks_required)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'exclusive_locks_required' attribute takes at least 1 argument}}
void elr_function_arg() EXCLUSIVE_LOCKS_REQUIRED(mu1);
@@ -1114,13 +1114,13 @@
// illegal attribute arguments
int elr_function_bad_1() EXCLUSIVE_LOCKS_REQUIRED(1); // \
- // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int elr_function_bad_2() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \
// expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}}
int elr_function_bad_3() EXCLUSIVE_LOCKS_REQUIRED(muDoublePointer); // \
- // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int elr_function_bad_4() EXCLUSIVE_LOCKS_REQUIRED(umu); // \
- // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}}
@@ -1136,7 +1136,7 @@
// takes one or more arguments, all locks (vars/fields)
void slr_function() __attribute__((shared_locks_required)); // \
- // expected-error {{attribute takes at least 1 argument}}
+ // expected-error {{'shared_locks_required' attribute takes at least 1 argument}}
void slr_function_arg() SHARED_LOCKS_REQUIRED(mu1);
@@ -1182,13 +1182,13 @@
// illegal attribute arguments
int slr_function_bad_1() SHARED_LOCKS_REQUIRED(1); // \
- // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
int slr_function_bad_2() SHARED_LOCKS_REQUIRED("mu"); // \
// expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}}
int slr_function_bad_3() SHARED_LOCKS_REQUIRED(muDoublePointer); // \
- // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
+ // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
int slr_function_bad_4() SHARED_LOCKS_REQUIRED(umu); // \
- // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+ // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}}
//-----------------------------------------//
@@ -1430,7 +1430,7 @@
int a GUARDED_BY(mu1_);
int b GUARDED_BY(mu2_);
int c GUARDED_BY(mu3_); // \
- // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class InheritanceTest::Derived3'}}
+ // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'InheritanceTest::Derived3'}}
void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1_, mu2_) {
a = 0;
diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp
index dd07125..04bd743 100644
--- a/test/SemaCXX/warn-unreachable.cpp
+++ b/test/SemaCXX/warn-unreachable.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -Wunreachable-code -Wno-unused-value
+// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -std=c++11 -Wunreachable-code-aggressive -Wno-unused-value
int &halt() __attribute__((noreturn));
int &live();
@@ -107,3 +107,223 @@
dead(); // expected-warning {{will never be executed}}
}
+// Handle 'try' code dominating a dead return.
+enum PR19040_test_return_t
+{ PR19040_TEST_FAILURE };
+namespace PR19040_libtest
+{
+ class A {
+ public:
+ ~A ();
+ };
+}
+PR19040_test_return_t PR19040_fn1 ()
+{
+ try
+ {
+ throw PR19040_libtest::A ();
+ } catch (...)
+ {
+ return PR19040_TEST_FAILURE;
+ }
+ return PR19040_TEST_FAILURE; // expected-warning {{will never be executed}}
+}
+
+__attribute__((noreturn))
+void raze();
+
+namespace std {
+template<typename T> struct basic_string {
+ basic_string(const T* x) {}
+ ~basic_string() {};
+};
+typedef basic_string<char> string;
+}
+
+std::string testStr() {
+ raze();
+ return ""; // expected-warning {{'return' will never be executed}}
+}
+
+std::string testStrWarn(const char *s) {
+ raze();
+ return s; // expected-warning {{will never be executed}}
+}
+
+bool testBool() {
+ raze();
+ return true; // expected-warning {{'return' will never be executed}}
+}
+
+static const bool ConditionVar = 1;
+int test_global_as_conditionVariable() {
+ if (ConditionVar)
+ return 1;
+ return 0; // no-warning
+}
+
+// Handle unreachable temporary destructors.
+class A {
+public:
+ A();
+ ~A();
+};
+
+__attribute__((noreturn))
+void raze(const A& x);
+
+void test_with_unreachable_tmp_dtors(int x) {
+ raze(x ? A() : A()); // no-warning
+}
+
+// Test sizeof - sizeof in enum declaration.
+enum { BrownCow = sizeof(long) - sizeof(char) };
+enum { CowBrown = 8 - 1 };
+
+
+int test_enum_sizeof_arithmetic() {
+ if (BrownCow)
+ return 1;
+ return 2;
+}
+
+int test_enum_arithmetic() {
+ if (CowBrown)
+ return 1;
+ return 2; // expected-warning {{never be executed}}
+}
+
+int test_arithmetic() {
+ if (8 -1)
+ return 1;
+ return 2; // expected-warning {{never be executed}}
+}
+
+int test_treat_const_bool_local_as_config_value() {
+ const bool controlValue = false;
+ if (!controlValue)
+ return 1;
+ test_treat_const_bool_local_as_config_value(); // no-warning
+ return 0;
+}
+
+int test_treat_non_const_bool_local_as_non_config_value() {
+ bool controlValue = false;
+ if (!controlValue)
+ return 1;
+ // There is no warning here because 'controlValue' isn't really
+ // a control value at all. The CFG will not treat this
+ // branch as unreachable.
+ test_treat_non_const_bool_local_as_non_config_value(); // no-warning
+ return 0;
+}
+
+void test_do_while(int x) {
+ // Handle trivial expressions with
+ // implicit casts to bool.
+ do {
+ break;
+ } while (0); // no-warning
+}
+
+class Frobozz {
+public:
+ Frobozz(int x);
+ ~Frobozz();
+};
+
+Frobozz test_return_object(int flag) {
+ return Frobozz(flag);
+ return Frobozz(42); // expected-warning {{'return' will never be executed}}
+}
+
+Frobozz test_return_object_control_flow(int flag) {
+ return Frobozz(flag);
+ return Frobozz(flag ? 42 : 24); // expected-warning {{code will never be executed}}
+}
+
+void somethingToCall();
+
+static constexpr bool isConstExprConfigValue() { return true; }
+
+int test_const_expr_config_value() {
+ if (isConstExprConfigValue()) {
+ somethingToCall();
+ return 0;
+ }
+ somethingToCall(); // no-warning
+ return 1;
+}
+int test_const_expr_config_value_2() {
+ if (!isConstExprConfigValue()) {
+ somethingToCall(); // no-warning
+ return 0;
+ }
+ somethingToCall();
+ return 1;
+}
+
+class Frodo {
+public:
+ static const bool aHobbit = true;
+};
+
+void test_static_class_var() {
+ if (Frodo::aHobbit)
+ somethingToCall();
+ else
+ somethingToCall(); // no-warning
+}
+
+void test_static_class_var(Frodo &F) {
+ if (F.aHobbit)
+ somethingToCall();
+ else
+ somethingToCall(); // no-warning
+}
+
+void test_unreachable_for_null_increment() {
+ for (unsigned i = 0; i < 10 ; ) // no-warning
+ break;
+}
+
+void test_unreachable_forrange_increment() {
+ int x[10] = { 0 };
+ for (auto i : x) { // expected-warning {{loop will run at most once (loop increment never executed)}}
+ break;
+ }
+}
+
+void calledFun() {}
+
+// Test "silencing" with parentheses.
+void test_with_paren_silencing(int x) {
+ if (false) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+ if ((false)) calledFun(); // no-warning
+
+ if (true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+ calledFun();
+ else
+ calledFun(); // expected-warning {{will never be executed}}
+
+ if ((true))
+ calledFun();
+ else
+ calledFun(); // no-warning
+
+ if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+ calledFun(); // expected-warning {{code will never be executed}}
+ else
+ calledFun();
+
+ if ((!true))
+ calledFun(); // no-warning
+ else
+ calledFun();
+
+ if (!(true))
+ calledFun(); // no-warning
+ else
+ calledFun();
+}
+
diff --git a/test/SemaCXX/warn-unused-attribute.cpp b/test/SemaCXX/warn-unused-attribute.cpp
index 72f96ee..f52de3b 100644
--- a/test/SemaCXX/warn-unused-attribute.cpp
+++ b/test/SemaCXX/warn-unused-attribute.cpp
@@ -1,20 +1,20 @@
// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -verify %s
-struct __attribute__((warn_unused)) Test
-{
- Test();
- ~Test();
- void use();
+struct __attribute__((warn_unused)) Test {
+ Test();
+ ~Test();
+ void use();
};
-struct TestNormal
-{
- TestNormal();
+struct TestNormal {
+ TestNormal();
};
-int main()
-{
- Test unused; // expected-warning {{unused variable 'unused'}}
- Test used;
- TestNormal normal;
- used.use();
+int main(void) {
+ Test unused; // expected-warning {{unused variable 'unused'}}
+ Test used;
+ TestNormal normal;
+ used.use();
+
+ int i __attribute__((warn_unused)) = 12; // expected-warning {{'warn_unused' attribute only applies to struct, union or class}}
+ return i;
}
diff --git a/test/SemaCXX/warn-unused-comparison.cpp b/test/SemaCXX/warn-unused-comparison.cpp
index 0153f21..8e6f0f4 100644
--- a/test/SemaCXX/warn-unused-comparison.cpp
+++ b/test/SemaCXX/warn-unused-comparison.cpp
@@ -3,6 +3,10 @@
struct A {
bool operator==(const A&);
bool operator!=(const A&);
+ bool operator<(const A&);
+ bool operator>(const A&);
+ bool operator<=(const A&);
+ bool operator>=(const A&);
A operator|=(const A&);
operator bool();
};
@@ -15,6 +19,11 @@
// 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}}
+ x < 7; // expected-warning {{relational comparison result unused}}
+ x > 7; // expected-warning {{relational comparison result unused}}
+ x <= 7; // expected-warning {{relational comparison result unused}}
+ x >= 7; // expected-warning {{relational comparison result unused}}
+
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}} \
@@ -25,6 +34,11 @@
// 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 {{relational comparison result unused}}
+ a > b; // expected-warning {{relational comparison result unused}}
+ a <= b; // expected-warning {{relational comparison result unused}}
+ a >= b; // expected-warning {{relational comparison result unused}}
+
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}}
diff --git a/test/SemaCXX/warn-unused-label-error.cpp b/test/SemaCXX/warn-unused-label-error.cpp
new file mode 100644
index 0000000..66b616f
--- /dev/null
+++ b/test/SemaCXX/warn-unused-label-error.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -verify %s
+
+static int unused_local_static;
+
+namespace PR8455 {
+ void f() {
+ A: // expected-warning {{unused label 'A'}}
+ __attribute__((unused)) int i; // attribute applies to variable
+ B: // attribute applies to label
+ __attribute__((unused)); int j; // expected-warning {{unused variable 'j'}}
+ }
+
+ void g() {
+ C: // unused label 'C' will not appear here because an error has occurred
+ __attribute__((unused))
+ #pragma weak unused_local_static // expected-error {{expected ';' after __attribute__}}
+ ;
+ }
+
+ void h() {
+ D: // expected-warning {{unused label 'D'}}
+ #pragma weak unused_local_static
+ __attribute__((unused)) // expected-warning {{declaration does not declare anything}}
+ ;
+ }
+}
diff --git a/test/SemaCXX/warn-unused-value.cpp b/test/SemaCXX/warn-unused-value.cpp
index 5e43d3e..4e1347c 100644
--- a/test/SemaCXX/warn-unused-value.cpp
+++ b/test/SemaCXX/warn-unused-value.cpp
@@ -32,7 +32,7 @@
}
namespace test2 {
- extern "C" {
+ extern "C++" {
namespace std {
template<typename T> struct basic_string {
struct X {};
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index 93d2f6f..ecb36ec 100644
--- a/test/SemaCXX/warn-unused-variables.cpp
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify %s
template<typename T> void f() {
T t;
t = 17;
@@ -115,6 +115,17 @@
}
}
+namespace PR19305 {
+ template<typename T> int n = 0; // no warning
+ int a = n<int>;
+
+ template<typename T> const int l = 0; // no warning
+ int b = l<int>;
+
+ // FIXME: It'd be nice to warn here.
+ template<typename T> int m = 0;
+}
+
namespace ctor_with_cleanups {
struct S1 {
~S1();
@@ -128,26 +139,3 @@
}
#include "Inputs/warn-unused-variables.h"
-
-namespace PR8455 {
- void f() {
- A: // expected-warning {{unused label 'A'}}
- __attribute__((unused)) int i; // attribute applies to variable
- B: // attribute applies to label
- __attribute__((unused)); int j; // expected-warning {{unused variable 'j'}}
- }
-
- void g() {
- C: // unused label 'C' will not appear here because an error occurs
- __attribute__((unused))
- #pragma weak unused_local_static // expected-error {{expected ';' after __attribute__}}
- ;
- }
-
- void h() {
- D: // expected-warning {{unused label 'D'}}
- #pragma weak unused_local_static
- __attribute__((unused)) // expected-warning {{declaration does not declare anything}}
- ;
- }
-}
diff --git a/test/SemaCXX/warn-weak-vtables.cpp b/test/SemaCXX/warn-weak-vtables.cpp
index 135e034..671ff29 100644
--- a/test/SemaCXX/warn-weak-vtables.cpp
+++ b/test/SemaCXX/warn-weak-vtables.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -Wweak-vtables -Wweak-template-vtables
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple %itanium_abi_triple -Wweak-vtables -Wweak-template-vtables
+// RUN: %clang_cc1 %s -fsyntax-only -triple %ms_abi_triple -Werror -Wno-weak-vtables -Wno-weak-template-vtables
struct A { // expected-warning {{'A' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
virtual void f() { }