diff options
Diffstat (limited to 'test/SemaCXX')
142 files changed, 3099 insertions, 271 deletions
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp index fb3107f..2bcbbca 100644 --- a/test/SemaCXX/MicrosoftExtensions.cpp +++ b/test/SemaCXX/MicrosoftExtensions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions -fexceptions +// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions -fexceptions // ::type_info is predeclared with forward class declartion @@ -30,6 +30,48 @@ struct Derived : Base { virtual void f3(); }; + +// MSVC allows type definition in anonymous union and struct +struct A +{ + union + { + int a; + struct B // expected-warning {{types declared in an anonymous union are a Microsoft extension}} + { + int c; + } d; + + union C // expected-warning {{types declared in an anonymous union are a Microsoft extension}} + { + int e; + int ee; + } f; + + typedef int D; // expected-warning {{types declared in an anonymous union are a Microsoft extension}} + struct F; // expected-warning {{types declared in an anonymous union are a Microsoft extension}} + }; + + struct + { + int a2; + + struct B2 // expected-warning {{types declared in an anonymous struct are a Microsoft extension}} + { + int c2; + } d2; + + union C2 // expected-warning {{types declared in an anonymous struct are a Microsoft extension}} + { + int e2; + int ee2; + } f2; + + typedef int D2; // expected-warning {{types declared in an anonymous struct are a Microsoft extension}} + struct F2; // expected-warning {{types declared in an anonymous struct are a Microsoft extension}} + }; +}; + // __stdcall handling struct M { int __stdcall addP(); @@ -42,3 +84,28 @@ void m1() { h1<int>(&M::addP); h1(&M::subtractP); } + +//MSVC allows forward enum declaration +enum ENUM; // expected-warning {{forward references to 'enum' types are a Microsoft extension}} +ENUM *var = 0; +ENUM var2 = (ENUM)3; +enum ENUM1* var3 = 0;// expected-warning {{forward references to 'enum' types are a Microsoft extension}} + + +enum ENUM2 { + ENUM2_a = (enum ENUM2) 4, + ENUM2_b = 0x9FFFFFFF, // expected-warning {{enumerator value is not representable in the underlying type 'int'}} + ENUM2_c = 0x100000000 // expected-warning {{enumerator value is not representable in the underlying type 'int'}} +}; + + +void f(long long); +void f(int); + +int main() +{ + // This is an ambiguous call in standard C++. + // This calls f(long long) in Microsoft mode because LL is always signed. + f(0xffffffffffffffffLL); + f(0xffffffffffffffffi64); +} diff --git a/test/SemaCXX/PR7944.cpp b/test/SemaCXX/PR7944.cpp new file mode 100644 index 0000000..fc52d10 --- /dev/null +++ b/test/SemaCXX/PR7944.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// PR7944 + +#define MACRO(x) x + +struct B { int f() { return 0; } }; +struct A { B* b() { return new B; } }; + +void g() { + A a; + MACRO(a.b->f()); // expected-error{{base of member reference has function type}} +} diff --git a/test/SemaCXX/PR8012.cpp b/test/SemaCXX/PR8012.cpp new file mode 100644 index 0000000..f2f07ad --- /dev/null +++ b/test/SemaCXX/PR8012.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x + +void foo (int operator+); // expected-error{{cannot be the name of a parameter}} diff --git a/test/SemaCXX/PR8755.cpp b/test/SemaCXX/PR8755.cpp new file mode 100644 index 0000000..07778dd --- /dev/null +++ b/test/SemaCXX/PR8755.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template <typename T> +struct A { + typedef int iterator; // expected-note{{declared here}} +}; + +template <typename T> +void f() { + class A <T> ::iterator foo; // expected-error{{elaborated type refers to a typedef}} +} + +void g() { + f<int>(); // expected-note{{in instantiation of function template}} +} + diff --git a/test/SemaCXX/PR8884.cpp b/test/SemaCXX/PR8884.cpp new file mode 100644 index 0000000..4026465 --- /dev/null +++ b/test/SemaCXX/PR8884.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only %s +extern "C" { + class bar { + friend struct foo; + static struct foo& baz (); + }; + struct foo { + void zed () { + bar::baz(); + } + }; +} diff --git a/test/SemaCXX/__null.cpp b/test/SemaCXX/__null.cpp index 3583655..1989a45 100644 --- a/test/SemaCXX/__null.cpp +++ b/test/SemaCXX/__null.cpp @@ -12,3 +12,10 @@ void f() { // Verify that null is evaluated as 0. int b[__null ? -1 : 1]; } + +struct A {}; + +void g() { + (void)(0 ? __null : A()); // expected-error {{non-pointer operand type 'A' incompatible with NULL}} + (void)(0 ? A(): __null); // expected-error {{non-pointer operand type 'A' incompatible with NULL}} +} diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp index ad079c2..48805e2 100644 --- a/test/SemaCXX/abstract.cpp +++ b/test/SemaCXX/abstract.cpp @@ -9,7 +9,7 @@ #endif class C { - virtual void f() = 0; // expected-note {{pure virtual function 'f'}} + virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}} }; static_assert(__is_abstract(C), "C has a pure virtual function"); @@ -25,7 +25,7 @@ class E : D { static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f"); -C *d = new C; // expected-error {{allocation of an object of abstract type 'C'}} +C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}} C c; // expected-error {{variable type 'C' is an abstract class}} void t1(C c); // expected-error {{parameter type 'C' is an abstract class}} @@ -38,8 +38,8 @@ struct S { void t3(const C&); void f() { - C(); // expected-error {{allocation of an object of abstract type 'C'}} - t3(C()); // expected-error {{allocation of an object of abstract type 'C'}} + C(); // expected-error {{allocating an object of abstract class type 'C'}} + t3(C()); // expected-error {{allocating an object of abstract class type 'C'}} } C e1[2]; // expected-error {{array of abstract class type 'C'}} @@ -64,7 +64,7 @@ class F { void u(F c); // expected-error {{parameter type 'F' is an abstract class}} }; - virtual void f() = 0; // expected-note {{pure virtual function 'f'}} + virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}} }; // Diagnosing in these cases is prohibitively expensive. We still @@ -193,14 +193,14 @@ namespace test1 { // rdar://problem/8302168 namespace test2 { struct X1 { - virtual void xfunc(void) = 0; // expected-note {{pure virtual function}} + virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}} void g(X1 parm7); // expected-error {{parameter type 'test2::X1' is an abstract class}} void g(X1 parm8[2]); // expected-error {{array of abstract class type 'test2::X1'}} }; template <int N> struct X2 { - virtual void xfunc(void) = 0; // expected-note {{pure virtual function}} + virtual void xfunc(void) = 0; // expected-note {{unimplemented pure virtual method}} void g(X2 parm10); // expected-error {{parameter type 'X2<N>' is an abstract class}} void g(X2 parm11[2]); // expected-error {{array of abstract class type 'X2<N>'}} }; @@ -219,11 +219,11 @@ namespace test3 { struct C { static C x; // expected-error {{abstract class}} - virtual void abstract() = 0; // expected-note {{pure virtual function}} + virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} }; struct D { - virtual void abstract() = 0; // expected-note {{pure virtual function}} + virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} static D x; // expected-error {{abstract class}} }; } @@ -231,21 +231,21 @@ namespace test3 { namespace test4 { template <class T> struct A { A x; // expected-error {{abstract class}} - virtual void abstract() = 0; // expected-note {{pure virtual function}} + virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} }; template <class T> struct B { - virtual void abstract() = 0; // expected-note {{pure virtual function}} + virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} B x; // expected-error {{abstract class}} }; template <class T> struct C { static C x; // expected-error {{abstract class}} - virtual void abstract() = 0; // expected-note {{pure virtual function}} + virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} }; template <class T> struct D { - virtual void abstract() = 0; // expected-note {{pure virtual function}} + virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}} static D x; // expected-error {{abstract class}} }; } diff --git a/test/SemaCXX/addr-of-overloaded-function-casting.cpp b/test/SemaCXX/addr-of-overloaded-function-casting.cpp new file mode 100644 index 0000000..cfd55ee --- /dev/null +++ b/test/SemaCXX/addr-of-overloaded-function-casting.cpp @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +void g(); + +void f(); // expected-note 9{{candidate function}} +void f(int); // expected-note 9{{candidate function}} + +template<class T> void t(T); // expected-note 6{{candidate function}} +template<class T> void t(T*); // expected-note 6{{candidate function}} + +template<class T> void u(T); + +int main() +{ + { bool b = (void (&)(char))f; } // expected-error{{does not match required type}} + { bool b = (void (*)(char))f; } // expected-error{{does not match required type}} + + { bool b = (void (&)(int))f; } //ok + { bool b = (void (*)(int))f; } //ok + + { bool b = static_cast<void (&)(char)>(f); } // expected-error{{does not match}} + { bool b = static_cast<void (*)(char)>(f); } // expected-error{{address of overloaded function}} + + { bool b = static_cast<void (&)(int)>(f); } //ok + { bool b = static_cast<void (*)(int)>(f); } //ok + + + { bool b = reinterpret_cast<void (&)(char)>(f); } // expected-error{{cannot resolve}} + { bool b = reinterpret_cast<void (*)(char)>(f); } // expected-error{{cannot resolve}} + + { bool b = reinterpret_cast<void (*)(char)>(g); } //ok + { bool b = static_cast<void (*)(char)>(g); } // expected-error{{not allowed}} + + { bool b = reinterpret_cast<void (&)(int)>(f); } // expected-error{{cannot resolve}} + { bool b = reinterpret_cast<void (*)(int)>(f); } // expected-error{{cannot resolve}} + + { bool b = (int (&)(char))t; } // expected-error{{does not match}} + { bool b = (int (*)(char))t; } // expected-error{{does not match}} + + { bool b = (void (&)(int))t; } //ok + { bool b = (void (*)(int))t; } //ok + + { bool b = static_cast<void (&)(char)>(t); } //ok + { bool b = static_cast<void (*)(char)>(t); } //ok + + { bool b = static_cast<void (&)(int)>(t); } //ok + { bool b = static_cast<void (*)(int)>(t); } //ok + + + { bool b = reinterpret_cast<void (&)(char)>(t); } // expected-error{{cannot resolve}} + { bool b = reinterpret_cast<void (*)(char)>(t); } // expected-error{{cannot resolve}} + + { bool b = reinterpret_cast<int (*)(char)>(g); } //ok + { bool b = static_cast<int (*)(char)>(t); } // expected-error{{cannot be static_cast}} + { bool b = static_cast<int (&)(char)>(t); } // expected-error{{does not match required}} + + { bool b = static_cast<void (&)(char)>(f); } // expected-error{{does not match}} +} diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp index b581b8a..a1079ff 100644 --- a/test/SemaCXX/addr-of-overloaded-function.cpp +++ b/test/SemaCXX/addr-of-overloaded-function.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -int f(double); -int f(int); +int f(double); // expected-note{{candidate function}} +int f(int); // expected-note{{candidate function}} int (*pfd)(double) = f; // selects f(double) int (*pfd2)(double) = &f; // selects f(double) @@ -9,7 +9,7 @@ int (*pfi)(int) = &f; // selects f(int) // FIXME: This error message is not very good. We need to keep better // track of what went wrong when the implicit conversion failed to // give a better error message here. -int (*pfe)(...) = &f; // expected-error{{cannot initialize a variable of type 'int (*)(...)' with an rvalue of type '<overloaded function type>'}} +int (*pfe)(...) = &f; // expected-error{{address of overloaded function 'f' does not match required type 'int (...)'}} int (&rfi)(int) = f; // selects f(int) int (&rfd)(double) = f; // selects f(double) @@ -57,11 +57,11 @@ struct B struct C { C &getC() { - return makeAC; // expected-error{{address of overloaded function 'makeAC' cannot be converted to type 'C'}} + return makeAC; // expected-error{{address of overloaded function 'makeAC'}} } - C &makeAC(); - const C &makeAC() const; + C &makeAC(); //expected-note{{candidate function}} + const C &makeAC() const; //expected-note{{candidate function}} static void f(); // expected-note{{candidate function}} static void f(int); // expected-note{{candidate function}} @@ -96,3 +96,52 @@ namespace PR7971 { static bool g(int, char); }; } + +namespace PR8033 { + template <typename T1, typename T2> int f(T1 *, const T2 *); // expected-note 2{{candidate function [with T1 = const int, T2 = int]}} + template <typename T1, typename T2> int f(const T1 *, T2 *); // expected-note 2{{candidate function [with T1 = int, T2 = const int]}} + int (*p)(const int *, const int *) = f; // expected-error{{address of overloaded function 'f' is ambiguous}} \ + // expected-error{{address of overloaded function 'f' is ambiguous}} + +} + +namespace PR8196 { + template <typename T> struct mcdata { + typedef int result_type; + }; + template <class T> + typename mcdata<T>::result_type wrap_mean(mcdata<T> const&); + void add_property(double(*)(mcdata<double> const &)); // expected-note{{candidate function not viable: no overload of 'wrap_mean' matching}} + void f() { + add_property(&wrap_mean); // expected-error{{no matching function for call to 'add_property'}} + } +} + +namespace PR7425 { + template<typename T> + void foo() + { + } + + struct B + { + template<typename T> + B(const T&) + { + } + }; + + void bar(const B& b) + { + } + + void bar2(const B& b = foo<int>) + { + } + + void test(int argc, char** argv) + { + bar(foo<int>); + bar2(); + } +} diff --git a/test/SemaCXX/address-of-temporary.cpp b/test/SemaCXX/address-of-temporary.cpp index decdc95..eb5dee5 100644 --- a/test/SemaCXX/address-of-temporary.cpp +++ b/test/SemaCXX/address-of-temporary.cpp @@ -5,8 +5,8 @@ struct X { X(int, int); }; -void *f0() { return &X(); } // expected-warning{{taking the address of a temporary object}} -void *f1() { return &X(1); } // expected-warning{{taking the address of a temporary object}} -void *f2() { return &X(1, 2); } // expected-warning{{taking the address of a temporary object}} -void *f3() { return &(X)1; } // expected-warning{{taking the address of a temporary object}} +void f0() { (void)&X(); } // expected-warning{{taking the address of a temporary object}} +void f1() { (void)&X(1); } // expected-warning{{taking the address of a temporary object}} +void f2() { (void)&X(1, 2); } // expected-warning{{taking the address of a temporary object}} +void f3() { (void)&(X)1; } // expected-warning{{taking the address of a temporary object}} diff --git a/test/SemaCXX/alignof-sizeof-reference.cpp b/test/SemaCXX/alignof-sizeof-reference.cpp index dd64d6a..761edfc 100644 --- a/test/SemaCXX/alignof-sizeof-reference.cpp +++ b/test/SemaCXX/alignof-sizeof-reference.cpp @@ -11,5 +11,5 @@ void test() { void f(); void f(int); void g() { - sizeof(&f); // expected-error{{invalid application of 'sizeof' to an overloaded function}} + sizeof(&f); // expected-error{{cannot resolve overloaded function from context}} } diff --git a/test/SemaCXX/altivec.cpp b/test/SemaCXX/altivec.cpp index cdfc00a..921bb73 100644 --- a/test/SemaCXX/altivec.cpp +++ b/test/SemaCXX/altivec.cpp @@ -6,13 +6,33 @@ void f(V4i a) { } -void test() +void test1() { V4i vGCC; vector int vAltiVec; f(vAltiVec); vGCC = vAltiVec; - vGCC = vGCC > vAltiVec; + bool res = vGCC > vAltiVec; vAltiVec = 0 ? vGCC : vGCC; } + +template<typename T> +void template_f(T param) { + param++; +} + +void test2() +{ + vector int vi; + ++vi; + vi++; + --vi; + vi--; + vector float vf; + vf++; + + ++vi=vi; + (++vi)[1]=1; + template_f(vi); +} diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp index fdb399b..bf45e5d 100644 --- a/test/SemaCXX/ambig-user-defined-conversions.cpp +++ b/test/SemaCXX/ambig-user-defined-conversions.cpp @@ -20,7 +20,7 @@ namespace test0 { const int Test1() { func(b1, f()); // expected-error {{call to 'func' is ambiguous}} - return f(); // expected-error {{conversion from 'test0::B' to 'int const' is ambiguous}} + return f(); // expected-error {{conversion from 'test0::B' to 'const int' is ambiguous}} } // This used to crash when comparing the two operands. @@ -57,3 +57,11 @@ namespace test1 { } } +namespace rdar8876150 { + struct A { operator bool(); }; + struct B : A { }; + struct C : A { }; + struct D : B, C { }; + + bool f(D d) { return !d; } // expected-error{{ambiguous conversion from derived class 'rdar8876150::D' to base class 'rdar8876150::A':}} +} diff --git a/test/SemaCXX/ambiguous-builtin-unary-operator.cpp b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp index 1aa09a6..836e319 100644 --- a/test/SemaCXX/ambiguous-builtin-unary-operator.cpp +++ b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp @@ -28,7 +28,7 @@ struct C1 : B1, A1 { }; void test(C1 c) { ++c; // expected-error {{use of overloaded operator '++' is ambiguous}} \ - // expected-note {{built-in candidate operator++(int volatile &)}} \ - // expected-note {{built-in candidate operator++(long volatile &)}} + // expected-note {{built-in candidate operator++(volatile int &)}} \ + // expected-note {{built-in candidate operator++(volatile long &)}} } diff --git a/test/SemaCXX/anonymous-union.cpp b/test/SemaCXX/anonymous-union.cpp index 5f84bcc..553ae65 100644 --- a/test/SemaCXX/anonymous-union.cpp +++ b/test/SemaCXX/anonymous-union.cpp @@ -155,3 +155,23 @@ namespace test4 { (void) a.us1; // expected-error {{private member}} } } + +typedef void *voidPtr; + +void f2() { + union { int **ctxPtr; void **voidPtr; }; +} + +void foo_PR6741() { + union { + char *m_a; + int *m_b; + }; + + if(1) { + union { + char *m_a; + int *m_b; + }; + } +} diff --git a/test/SemaCXX/array-bounds.cpp b/test/SemaCXX/array-bounds.cpp new file mode 100644 index 0000000..0286c01 --- /dev/null +++ b/test/SemaCXX/array-bounds.cpp @@ -0,0 +1,93 @@ +// RUN: %clang_cc1 -verify %s + +int foo() { + int x[2]; // expected-note 4 {{array 'x' declared here}} + int y[2]; // expected-note 2 {{array 'y' declared here}} + int *p = &y[2]; // no-warning + (void) sizeof(x[2]); // no-warning + y[2] = 2; // expected-warning {{array index of '2' indexes past the end of an array (that contains 2 elements)}} + return x[2] + // expected-warning {{array index of '2' indexes past the end of an array (that contains 2 elements)}} + y[-1] + // expected-warning {{array index of '-1' indexes before the beginning of the array}} + x[sizeof(x)] + // expected-warning {{array index of '8' indexes past the end of an array (that contains 2 elements)}} + x[sizeof(x) / sizeof(x[0])] + // expected-warning {{array index of '2' indexes past the end of an array (that contains 2 elements)}} + x[sizeof(x) / sizeof(x[0]) - 1] + // no-warning + x[sizeof(x[2])]; // expected-warning {{array index of '4' indexes past the end of an array (that contains 2 elements)}} +} + +// This code example tests that -Warray-bounds works with arrays that +// are template parameters. +template <char *sz> class Qux { + bool test() { return sz[0] == 'a'; } +}; + +void f1(int a[1]) { + int val = a[3]; // no warning for function argumnet +} + +void f2(const int (&a)[1]) { // expected-note {{declared here}} + int val = a[3]; // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 elements)}} +} + +void test() { + struct { + int a[0]; + } s2; + s2.a[3] = 0; // no warning for 0-sized array + + union { + short a[2]; // expected-note {{declared here}} + char c[4]; + } u; + u.a[3] = 1; // expected-warning {{array index of '3' indexes past the end of an array (that contains 2 elements)}} + u.c[3] = 1; // no warning + + const int const_subscript = 3; + int array[1]; // expected-note {{declared here}} + array[const_subscript] = 0; // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 elements)}} + + int *ptr; + ptr[3] = 0; // no warning for pointer references + int array2[] = { 0, 1, 2 }; // expected-note 2 {{declared here}} + + array2[3] = 0; // expected-warning {{array index of '3' indexes past the end of an array (that contains 3 elements)}} + array2[2+2] = 0; // expected-warning {{array index of '4' indexes past the end of an array (that contains 3 elements)}} + + const char *str1 = "foo"; + char c1 = str1[5]; // no warning for pointers + + const char str2[] = "foo"; // expected-note {{declared here}} + char c2 = str2[5]; // expected-warning {{array index of '5' indexes past the end of an array (that contains 4 elements)}} + + int (*array_ptr)[1]; + (*array_ptr)[3] = 1; // expected-warning {{array index of '3' indexes past the end of an array (that contains 1 elements)}} +} + +template <int I> struct S { + char arr[I]; // expected-note 3 {{declared here}} +}; +template <int I> void f() { + S<3> s; + s.arr[4] = 0; // expected-warning 2 {{array index of '4' indexes past the end of an array (that contains 3 elements)}} + s.arr[I] = 0; // expected-warning {{array index of '5' indexes past the end of an array (that contains 3 elements)}} +} + +void test_templates() { + f<5>(); // expected-note {{in instantiation}} +} + +#define SIZE 10 +#define ARR_IN_MACRO(flag, arr, idx) flag ? arr[idx] : 1 + +int test_no_warn_macro_unreachable() { + int arr[SIZE]; // expected-note 2 {{array 'arr' declared here}} + // FIXME: We don't want to warn for the first case. + return ARR_IN_MACRO(0, arr, SIZE) + // expected-warning{{array index of '10' indexes past the end of an array (that contains 10 elements)}} + ARR_IN_MACRO(1, arr, SIZE); // expected-warning{{array index of '10' indexes past the end of an array (that contains 10 elements)}} +} + +// This exhibited an assertion failure for a 32-bit build of Clang. +int test_pr9240() { + short array[100]; // expected-note {{array 'array' declared here}} + return array[(unsigned long long) 100]; // expected-warning {{array index of '100' indexes past the end of an array (that contains 100 elements)}} +} + diff --git a/test/SemaCXX/arrow-operator.cpp b/test/SemaCXX/arrow-operator.cpp index 29b23ed..6535a0a 100644 --- a/test/SemaCXX/arrow-operator.cpp +++ b/test/SemaCXX/arrow-operator.cpp @@ -23,3 +23,16 @@ void f(C &c, D& d, E& e) { d->f(); e->f(); // expected-error{{incomplete definition of type}} } + +// rdar://8875304 +namespace rdar8875304 { +class Point {}; +class Line_Segment{ public: Line_Segment(const Point&){} }; +class Node { public: Point Location(){ Point p; return p; } }; + +void f() +{ + Node** node1; + Line_Segment(node1->Location()); // expected-error {{not a structure or union}} +} +} diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp index 8fbf50c..40fe0e0 100644 --- a/test/SemaCXX/attr-cxx0x.cpp +++ b/test/SemaCXX/attr-cxx0x.cpp @@ -1,16 +1,8 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s -int final_fail [[final]]; //expected-error {{'final' attribute only applies to virtual method or class types}} - -struct [[final]] final_base { }; // expected-note {{'final_base' declared here}} -struct final_child : final_base { }; // expected-error {{derivation from 'final' struct final_base}} - -struct final_member { virtual void quux [[final]] (); }; // expected-note {{overridden virtual function is here}} -struct final_override : final_member { virtual void quux (); }; // expected-error {{declaration of 'quux' overrides a 'final' function}} - int align_illegal [[align(3)]]; //expected-error {{requested alignment is not a power of 2}} char align_big [[align(int)]]; -int align_small [[align(1)]]; +int align_small [[align(1)]]; // FIXME: this should be rejected int align_multiple [[align(1), align(8), align(1)]]; struct align_member { @@ -18,19 +10,7 @@ struct align_member { }; static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong"); -static_assert(alignof(align_small) == alignof(int), "j's alignment is wrong"); +static_assert(alignof(align_small) == 1, "j's alignment is wrong"); static_assert(alignof(align_multiple) == 8, "l's alignment is wrong"); static_assert(alignof(align_member) == 8, "quuux's alignment is wrong"); static_assert(sizeof(align_member) == 8, "quuux's size is wrong"); - -int bc_fail [[base_check]]; // expected-error {{'base_check' attribute only applies to class types}} -int hiding_fail [[hiding]]; // expected-error {{'hiding' attribute only applies to member types}} -int override_fail [[override]]; // expected-error {{'override' attribute only applies to virtual method types}} - -struct base { - virtual void function(); - virtual void other_function(); -}; - -struct [[base_check, base_check]] bc : base { // expected-error {{'base_check' attribute cannot be repeated}} -}; diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp index 2164f9d..fe7c833 100644 --- a/test/SemaCXX/attr-deprecated.cpp +++ b/test/SemaCXX/attr-deprecated.cpp @@ -190,3 +190,46 @@ namespace test5 { {} }; } + +// rdar://problem/8518751 +namespace test6 { + enum __attribute__((deprecated)) A { + a0 + }; + void testA() { + A x; // expected-warning {{'A' is deprecated}} + x = a0; + } + + enum B { + b0 __attribute__((deprecated)), + b1 + }; + void testB() { + B x; + x = b0; // expected-warning {{'b0' is deprecated}} + x = b1; + } + + template <class T> struct C { + enum __attribute__((deprecated)) Enum { + c0 + }; + }; + void testC() { + C<int>::Enum x; // expected-warning {{'Enum' is deprecated}} + x = C<int>::c0; + } + + template <class T> struct D { + enum Enum { + d0, + d1 __attribute__((deprecated)), + }; + }; + void testD() { + D<int>::Enum x; + x = D<int>::d0; + x = D<int>::d1; // expected-warning {{'d1' is deprecated}} + } +} diff --git a/test/SemaCXX/attr-format.cpp b/test/SemaCXX/attr-format.cpp index 0c1eb53..da134a1 100644 --- a/test/SemaCXX/attr-format.cpp +++ b/test/SemaCXX/attr-format.cpp @@ -1,8 +1,35 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wformat-nonliteral -verify %s struct S { static void f(const char*, ...) __attribute__((format(printf, 1, 2))); + static const char* f2(const char*) __attribute__((format_arg(1))); // GCC has a hidden 'this' argument in member functions which is why // the format argument is argument 2 here. void g(const char*, ...) __attribute__((format(printf, 2, 3))); + const char* g2(const char*) __attribute__((format_arg(2))); + + void h(const char*, ...) __attribute__((format(printf, 1, 4))); // \ + expected-error{{implicit this argument as the format string}} + void h2(const char*, ...) __attribute__((format(printf, 2, 1))); // \ + expected-error{{out of bounds}} + const char* h3(const char*) __attribute__((format_arg(1))); // \ + expected-error{{invalid for the implicit this argument}} }; + +// PR5521 +struct A { void a(const char*,...) __attribute((format(printf,2,3))); }; +void b(A x) { + x.a("%d", 3); +} + +// PR8625: correctly interpret static member calls as not having an implicit +// 'this' argument. +namespace PR8625 { + struct S { + static void f(const char*, const char*, ...) + __attribute__((format(printf, 2, 3))); + }; + void test(S s, const char* str) { + s.f(str, "%s", str); + } +} diff --git a/test/SemaCXX/attr-nonnull.cpp b/test/SemaCXX/attr-nonnull.cpp new file mode 100644 index 0000000..19d6642 --- /dev/null +++ b/test/SemaCXX/attr-nonnull.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct S { + static void f(const char*, const char*) __attribute__((nonnull(1))); + + // GCC has a hidden 'this' argument in member functions, so the middle + // argument is the one that must not be null. + void g(const char*, const char*, const char*) __attribute__((nonnull(3))); + + void h(const char*) __attribute__((nonnull(1))); // \ + expected-error{{invalid for the implicit this argument}} +}; + +void test(S s) { + s.f(0, ""); // expected-warning{{null passed}} + s.f("", 0); + s.g("", 0, ""); // expected-warning{{null passed}} + s.g(0, "", 0); +} + +namespace rdar8769025 { + __attribute__((nonnull)) void f0(int *&p); + __attribute__((nonnull)) void f1(int * const &p); + __attribute__((nonnull(2))) void f2(int i, int * const &p); + + void test_f1() { + f1(0); // expected-warning{{null passed to a callee which requires a non-null argument}} + f2(0, 0); // expected-warning{{null passed to a callee which requires a non-null argument}} + } +} diff --git a/test/SemaCXX/attr-weak.cpp b/test/SemaCXX/attr-weak.cpp new file mode 100644 index 0000000..b6a9e0a --- /dev/null +++ b/test/SemaCXX/attr-weak.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %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 { + int test3 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} + void test4() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} +} + +struct Test5 { + static void test5() __attribute__((weak)); // no error +}; + +namespace { + struct Test6 { + static void test6() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}} + }; +} + +template <class T> struct Test7 { + void test7() __attribute__((weak)) {} +}; +namespace { class Internal; } +template struct Test7<Internal>; +template struct Test7<int>; diff --git a/test/SemaCXX/attr-weakref.cpp b/test/SemaCXX/attr-weakref.cpp index 5773acc..a345791 100644 --- a/test/SemaCXX/attr-weakref.cpp +++ b/test/SemaCXX/attr-weakref.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s // GCC will accept anything as the argument of weakref. Should we // check for an existing decl? @@ -24,8 +24,8 @@ class c { static int a __attribute__((weakref ("v2"))); // expected-error {{declaration of 'a' must be in a global context}} static int b() __attribute__((weakref ("f3"))); // expected-error {{declaration of 'b' must be in a global context}} }; -int a7() __attribute__((weakref ("f1"))); // expected-error {{declaration of 'a7' must be static}} -int a8 __attribute__((weakref ("v1"))); // expected-error {{declaration of 'a8' must be static}} +int a7() __attribute__((weakref ("f1"))); // expected-error {{weakref declaration must have internal linkage}} +int a8 __attribute__((weakref ("v1"))); // expected-error {{weakref declaration must have internal linkage}} // gcc accepts this -int a9 __attribute__((weakref)); // expected-error {{declaration of 'a9' must be static}} +int a9 __attribute__((weakref)); // expected-error {{weakref declaration must have internal linkage}} diff --git a/test/SemaCXX/block-call.cpp b/test/SemaCXX/block-call.cpp new file mode 100644 index 0000000..d519911 --- /dev/null +++ b/test/SemaCXX/block-call.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -x c++ -fsyntax-only -verify %s -fblocks + +int (*FP)(); +int (^IFP) (); +int (^II) (int); +int main() { + int (*FPL) (int) = FP; // expected-error {{cannot initialize a variable of type 'int (*)(int)' with an lvalue of type 'int (*)()'}} + + // For Blocks, the ASTContext::typesAreBlockCompatible() makes sure this is an error. + int (^PFR) (int) = IFP; // expected-error {{cannot initialize a variable of type 'int (^)(int)' with an lvalue of type 'int (^)()'}} + PFR = II; // OK + + int (^IFP) () = PFR; // OK + + + const int (^CIC) () = IFP; // OK - initializing 'const int (^)()' with an expression of type 'int (^)()'}} + + const int (^CICC) () = CIC; + + + int * const (^IPCC) () = 0; + + int * const (^IPCC1) () = IPCC; + + int * (^IPCC2) () = IPCC; // expected-error {{cannot initialize a variable of type 'int *(^)()' with an lvalue of type 'int *const (^)()'}} + + int (^IPCC3) (const int) = PFR; + + int (^IPCC4) (int, char (^CArg) (double)); + + int (^IPCC5) (int, char (^CArg) (double)) = IPCC4; + + int (^IPCC6) (int, char (^CArg) (float)) = IPCC4; // expected-error {{cannot initialize a variable of type 'int (^)(int, char (^)(float))' with an lvalue of type}} + + IPCC2 = 0; + IPCC2 = 1; + int (^x)() = 0; + int (^y)() = 3; // expected-error {{cannot initialize a variable of type 'int (^)()' with an rvalue of type 'int'}} + int a = 1; + int (^z)() = a+4; // expected-error {{cannot initialize a variable of type 'int (^)()' with an rvalue of type 'int'}} +} + +int blah() { + int (^IFP) (float); + char (^PCP)(double, double, char); + + IFP(1.0); + IFP (1.0, 2.0); // expected-error {{too many arguments to block call}} + + char ch = PCP(1.0, 2.0, 'a'); + return PCP(1.0, 2.0); // expected-error {{too few arguments to block}} +} diff --git a/test/SemaCXX/borland-extensions.cpp b/test/SemaCXX/borland-extensions.cpp index c33527c..4831530 100644 --- a/test/SemaCXX/borland-extensions.cpp +++ b/test/SemaCXX/borland-extensions.cpp @@ -24,3 +24,30 @@ void m2() { i = h2<int>(&M::addP); f = h2(&M::subtractP); } + +// 3. test other calling conventions +int _cdecl fa3(); +int _fastcall fc3(); +int _stdcall fd3(); + +// 4. test __uuidof() +typedef struct _GUID { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[ 8 ]; +} GUID; + +struct __declspec(uuid("{12345678-1234-1234-1234-123456789abc}")) Foo; +struct Data { + GUID const* Guid; +}; + +void t4() { + unsigned long data; + + const GUID guid_inl = __uuidof(Foo); + Data ata1 = { &guid_inl}; + data = ata1.Guid->Data1; +} + diff --git a/test/SemaCXX/builtin-ptrtomember-ambig.cpp b/test/SemaCXX/builtin-ptrtomember-ambig.cpp index 3e0dfbb..32a893d 100644 --- a/test/SemaCXX/builtin-ptrtomember-ambig.cpp +++ b/test/SemaCXX/builtin-ptrtomember-ambig.cpp @@ -19,9 +19,9 @@ struct C : B { void foo(C c, int A::* pmf) { // FIXME. Why so many built-in candidates? int i = c->*pmf; // expected-error {{use of overloaded operator '->*' is ambiguous}} \ - // expected-note {{built-in candidate operator->*(struct A const *, int const struct A::*)}} \ - // expected-note {{built-in candidate operator->*(struct A const *, int struct A::*)}} \ - // expected-note {{built-in candidate operator->*(struct A *, int const struct A::*)}} \ + // expected-note {{built-in candidate operator->*(const struct A *, const int struct A::*)}} \ + // expected-note {{built-in candidate operator->*(const struct A *, int struct A::*)}} \ + // expected-note {{built-in candidate operator->*(struct A *, const int struct A::*)}} \ // expected-note {{built-in candidate operator->*(struct A *, int struct A::*)}} } diff --git a/test/SemaCXX/builtin_objc_msgSend.cpp b/test/SemaCXX/builtin_objc_msgSend.cpp new file mode 100644 index 0000000..0e90d54 --- /dev/null +++ b/test/SemaCXX/builtin_objc_msgSend.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify +// rdar://8686888 + +typedef struct objc_selector *SEL; +typedef struct objc_object *id; + +extern "C" __attribute__((visibility("default"))) id objc_msgSend(id self, SEL op, ...) + __attribute__((visibility("default"))); + +inline void TCFReleaseGC(void * object) +{ + static SEL SEL_release; + objc_msgSend((id)object, SEL_release); +} diff --git a/test/SemaCXX/c99-variable-length-array.cpp b/test/SemaCXX/c99-variable-length-array.cpp index 7dc912a..98df1db 100644 --- a/test/SemaCXX/c99-variable-length-array.cpp +++ b/test/SemaCXX/c99-variable-length-array.cpp @@ -114,3 +114,10 @@ namespace rdar8021385 { }; B<A> a; } + +namespace PR8209 { + void f(int n) { + typedef int vla_type[n]; // expected-warning{{variable length arrays are a C99 feature, accepted as an extension}} + (void)new vla_type; // expected-error{{variably}} + } +} diff --git a/test/SemaCXX/c99.cpp b/test/SemaCXX/c99.cpp index b0bd45d..cda069c 100644 --- a/test/SemaCXX/c99.cpp +++ b/test/SemaCXX/c99.cpp @@ -1,3 +1,9 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s void f1(int i[static 5]) { // expected-error{{C99}} } + +struct Point { int x; int y; }; + +Point p1 = { .x = 17, // expected-warning{{designated initializers are a C99 feature, accepted in C++ as an extension}} + y: 25 }; // expected-warning{{designated initializers are a C99 feature, accepted in C++ as an extension}} \ + // expected-warning{{use of GNU old-style field designator extension}} diff --git a/test/SemaCXX/cast-conversion.cpp b/test/SemaCXX/cast-conversion.cpp index d68e789..80707d1 100644 --- a/test/SemaCXX/cast-conversion.cpp +++ b/test/SemaCXX/cast-conversion.cpp @@ -8,14 +8,14 @@ struct A { A(R); }; -struct B { - B(A); +struct B { // expected-note 3 {{candidate constructor (the implicit copy constructor) not viable}} + B(A); // expected-note 3 {{candidate constructor not viable}} }; int main () { - B(10); // expected-error {{functional-style cast from 'int' to 'B' is not allowed}} - (B)10; // expected-error {{C-style cast from 'int' to 'B' is not allowed}} - static_cast<B>(10); // expected-error {{static_cast from 'int' to 'B' is not allowed}} \\ + B(10); // expected-error {{no matching conversion for functional-style cast from 'int' to 'B'}} + (B)10; // expected-error {{no matching conversion for C-style cast from 'int' to 'B'}} + static_cast<B>(10); // expected-error {{no matching conversion for static_cast from 'int' to 'B'}} \\ // expected-warning {{expression result unused}} } diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp index 9d9508b..52140cb 100644 --- a/test/SemaCXX/class.cpp +++ b/test/SemaCXX/class.cpp @@ -12,16 +12,18 @@ public: } class NestedC { + public: + NestedC(int); void m() { sx = 0; - x = 0; // expected-error {{error: invalid use of nonstatic data member 'x'}} + x = 0; // expected-error {{invalid use of nonstatic data member 'x'}} } }; int b : 1, w : 2; int : 1, : 2; typedef int E : 1; // expected-error {{typedef member 'E' cannot be a bit-field}} - static int sb : 1; // expected-error {{error: static member 'sb' cannot be a bit-field}} + static int sb : 1; // expected-error {{static member 'sb' cannot be a bit-field}} static int vs; typedef int func(); @@ -32,10 +34,10 @@ public: enum E1 { en1, en2 }; - int i = 0; // expected-error {{error: 'i' can only be initialized if it is a static const integral data member}} - static int si = 0; // expected-error {{error: 'si' can only be initialized if it is a static const integral data member}} - static const NestedC ci = 0; // expected-error {{error: 'ci' can only be initialized if it is a static const integral data member}} - static const int nci = vs; // expected-error {{in-class initializer is not an integral constant expression}} + int i = 0; // expected-error {{fields can only be initialized in constructors}} + static int si = 0; // expected-error {{non-const static data member must be initialized out of line}} + static const NestedC ci = 0; // expected-error {{static data member of type 'const C::NestedC' must be initialized out of line}} + static const int nci = vs; // expected-error {{in-class initializer is not a constant expression}} static const int vi = 0; static const E evi = 0; @@ -89,7 +91,7 @@ struct C3 { void f() { const C3 c3 = { 1, 2 }; - (void)static_cast<int*>(&c3.i); // expected-error {{static_cast from 'int const *' to 'int *' is not allowed}} + (void)static_cast<int*>(&c3.i); // expected-error {{static_cast from 'const int *' to 'int *' is not allowed}} // but no error here (void)static_cast<int*>(&c3.j); } @@ -115,7 +117,7 @@ struct C4 { struct S { void f(); // expected-note 1 {{previous declaration}} - void S::f() {} // expected-error {{class member cannot be redeclared}} expected-note {{previous declaration}} expected-note {{previous definition}} + void S::f() {} // expected-warning {{extra qualification on member}} expected-error {{class member cannot be redeclared}} expected-note {{previous declaration}} expected-note {{previous definition}} void f() {} // expected-error {{class member cannot be redeclared}} expected-error {{redefinition}} }; @@ -165,3 +167,24 @@ namespace rdar8066414 { C() {} } // expected-error{{expected ';' after class}} } + +namespace rdar8367341 { + float foo(); + + struct A { + static const float x = 5.0f; // expected-warning {{in-class initializer for static data member of type 'const float' is a C++0x extension}} + static const float y = foo(); // expected-warning {{in-class initializer for static data member of type 'const float' is a C++0x extension}} expected-error {{in-class initializer is not a constant expression}} + }; +} + +namespace with_anon { +struct S { + union { + char c; + }; +}; + +void f() { + S::c; // expected-error {{invalid use of nonstatic data member}} +} +} diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp index ebecc06..ca8af21 100644 --- a/test/SemaCXX/compare.cpp +++ b/test/SemaCXX/compare.cpp @@ -206,3 +206,9 @@ void test2(int i, void *vp) { if (vp < 0) { } if (test1 < e) { } // expected-error{{comparison between pointer and integer}} } + +// PR7536 +static const unsigned int kMax = 0; +int pr7536() { + return (kMax > 0); +} diff --git a/test/SemaCXX/composite-pointer-type.cpp b/test/SemaCXX/composite-pointer-type.cpp index e8b0920..06fc8f4 100644 --- a/test/SemaCXX/composite-pointer-type.cpp +++ b/test/SemaCXX/composite-pointer-type.cpp @@ -53,8 +53,8 @@ bool f(Matrix4 m1, const Matrix4 m2) { // PR6346 bool f1(bool b, void **p, const void **q) { - if (p == q) // expected-warning{{comparison of distinct pointer types ('void **' and 'void const **') uses non-standard composite pointer type 'void const *const *'}} + if (p == q) // expected-warning{{comparison of distinct pointer types ('void **' and 'const void **') uses non-standard composite pointer type 'const void *const *'}} return false; - return b? p : q; // expected-warning{{incompatible operand types ('void **' and 'void const **') use non-standard composite pointer type 'void const *const *'}} + return b? p : q; // expected-warning{{incompatible operand types ('void **' and 'const void **') use non-standard composite pointer type 'const void *const *'}} } diff --git a/test/SemaCXX/compound-literal.cpp b/test/SemaCXX/compound-literal.cpp new file mode 100644 index 0000000..fe0e45d --- /dev/null +++ b/test/SemaCXX/compound-literal.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// http://llvm.org/PR7905 +namespace PR7905 { +struct S; // expected-note {{forward declaration}} +void foo1() { + (void)(S[]) {{3}}; // expected-error {{array has incomplete element type}} +} + +template <typename T> struct M { T m; }; +void foo2() { + (void)(M<short> []) {{3}}; +} +} diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp index daa86f6..61d1762 100644 --- a/test/SemaCXX/condition.cpp +++ b/test/SemaCXX/condition.cpp @@ -42,3 +42,12 @@ void test2() { if (int *ip = ip) { } } + +// Make sure we do function/array decay. +void test3() { + if ("help") + (void) 0; + + if (test3) + (void) 0; +} diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp index 065179b..1da9a17 100644 --- a/test/SemaCXX/conditional-expr.cpp +++ b/test/SemaCXX/conditional-expr.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -Wsign-compare %s +// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify -std=c++0x -Wsign-compare %s // C++ rules for ?: are a lot stricter than C rules, and have to take into // account more conversion options. @@ -7,7 +7,10 @@ struct ToBool { explicit operator bool(); }; struct B; -struct A { A(); A(const B&); }; // expected-note 2 {{candidate constructor}} +struct A { + A(); + A(const B&); // expected-note 2 {{candidate constructor}} +}; struct B { operator A() const; }; // expected-note 2 {{candidate function}} struct I { operator int(); }; struct J { operator I(); }; @@ -106,8 +109,8 @@ void test() i1 = (i1 ? Base() : Derived()).trick(); i1 = (i1 ? Derived() : Base()).trick(); // should fail: const lost - (void)(i1 ? Base() : constder()); // expected-error {{incompatible operand types ('Base' and 'Derived const')}} - (void)(i1 ? constder() : Base()); // expected-error {{incompatible operand types ('Derived const' and 'Base')}} + (void)(i1 ? Base() : constder()); // expected-error {{incompatible operand types ('Base' and 'const Derived')}} + (void)(i1 ? constder() : Base()); // expected-error {{incompatible operand types ('const Derived' and 'Base')}} Priv priv; Fin fin; @@ -304,3 +307,17 @@ namespace PR7598 { } } + +namespace PR9236 { +#define NULL 0L + void f() { + int i; + (void)(true ? A() : NULL); // expected-error{{non-pointer operand type 'A' incompatible with NULL}} + (void)(true ? NULL : A()); // expected-error{{non-pointer operand type 'A' incompatible with NULL}} + (void)(true ? 0 : A()); // expected-error{{incompatible operand types}} + (void)(true ? nullptr : A()); // expected-error{{non-pointer operand type 'A' incompatible with nullptr}} + (void)(true ? nullptr : i); // expected-error{{non-pointer operand type 'int' incompatible with nullptr}} + (void)(true ? __null : A()); // expected-error{{non-pointer operand type 'A' incompatible with NULL}} + (void)(true ? (void*)0 : A()); // expected-error{{incompatible operand types}} + } +} diff --git a/test/SemaCXX/const-cast.cpp b/test/SemaCXX/const-cast.cpp index 50bd316..62851f8 100644 --- a/test/SemaCXX/const-cast.cpp +++ b/test/SemaCXX/const-cast.cpp @@ -45,16 +45,16 @@ char ***good_const_cast_test(ccvpcvpp var) short *bad_const_cast_test(char const *volatile *const volatile *var) { // Different pointer levels. - char **var2 = const_cast<char**>(var); // expected-error {{const_cast from 'char const *volatile *const volatile *' to 'char **' is not allowed}} + char **var2 = const_cast<char**>(var); // expected-error {{const_cast from 'const char *volatile *const volatile *' to 'char **' is not allowed}} // Different final type. - short ***var3 = const_cast<short***>(var); // expected-error {{const_cast from 'char const *volatile *const volatile *' to 'short ***' is not allowed}} + short ***var3 = const_cast<short***>(var); // expected-error {{const_cast from 'const char *volatile *const volatile *' to 'short ***' is not allowed}} // Rvalue to reference. char ***&var4 = const_cast<cpppr>(&var2); // expected-error {{const_cast from rvalue to reference type 'cpppr'}} // Non-pointer. char v = const_cast<char>(**var2); // expected-error {{const_cast to 'char', which is not a reference, pointer-to-object, or pointer-to-data-member}} const int *ar[100] = {0}; // Not even lenient g++ accepts this. - int *(*rar)[100] = const_cast<int *(*)[100]>(&ar); // expected-error {{const_cast from 'int const *(*)[100]' to 'int *(*)[100]' is not allowed}} + int *(*rar)[100] = const_cast<int *(*)[100]>(&ar); // expected-error {{const_cast from 'const int *(*)[100]' to 'int *(*)[100]' is not allowed}} f fp1 = 0; // 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}} diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp index 31d5330..e439a76 100644 --- a/test/SemaCXX/constructor-initializer.cpp +++ b/test/SemaCXX/constructor-initializer.cpp @@ -144,9 +144,13 @@ int IntWrapper(int i) { return 0; }; class InitializeUsingSelfExceptions { int A; int B; + int C; + void *P; InitializeUsingSelfExceptions(int B) : A(IntWrapper(A)), // Due to a conservative implementation, we do not report warnings inside function/ctor calls even though it is possible to do so. - B(B) {} // Not a warning; B is a local variable. + B(B), // Not a warning; B is a local variable. + C(sizeof(C)), // sizeof doesn't reference contents, do not warn + P(&P) {} // address-of doesn't reference contents (the pointer may be dereferenced in the same expression but it would be rare; and weird) }; class CopyConstructorTest { @@ -235,3 +239,32 @@ namespace test3 { } }; } + +// PR8075 +namespace PR8075 { + +struct S1 { + enum { FOO = 42 }; + static const int bar = 42; + static int baz(); + S1(int); +}; + +const int S1::bar; + +struct S2 { + S1 s1; + S2() : s1(s1.FOO) {} +}; + +struct S3 { + S1 s1; + S3() : s1(s1.bar) {} +}; + +struct S4 { + S1 s1; + S4() : s1(s1.baz()) {} +}; + +} diff --git a/test/SemaCXX/constructor.cpp b/test/SemaCXX/constructor.cpp index 9ef5c98..f3b910d 100644 --- a/test/SemaCXX/constructor.cpp +++ b/test/SemaCXX/constructor.cpp @@ -15,7 +15,8 @@ class Foo { virtual Foo(double); // expected-error{{constructor cannot be declared 'virtual'}} Foo(long) const; // expected-error{{'const' qualifier is not allowed on a constructor}} - int Foo(int, int); // expected-error{{constructor cannot have a return type}} + int Foo(int, int); // expected-error{{constructor cannot have a return type}} \ + // expected-error{{member 'Foo' has the same name as its class}} }; Foo::Foo(const Foo&) { } diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp index 07281e1..61c8ada 100644 --- a/test/SemaCXX/conversion-function.cpp +++ b/test/SemaCXX/conversion-function.cpp @@ -50,7 +50,7 @@ class A { }; class B : public A { public: operator A&() const; // expected-warning{{conversion function converting 'B' to its base class 'A' will never be used}} - operator const void() const; // expected-warning{{conversion function converting 'B' to 'void const' will never be used}} + operator const void() const; // expected-warning{{conversion function converting 'B' to 'const void' will never be used}} operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}} }; @@ -325,3 +325,31 @@ namespace rdar8018274 { int i = ed; } } + +namespace PR8065 { + template <typename T> struct Iterator; + template <typename T> struct Container; + + template<> + struct Iterator<int> { + typedef Container<int> container_type; + }; + + template <typename T> + struct Container { + typedef typename Iterator<T>::container_type X; + operator X(void) { return X(); } + }; + + Container<int> test; +} + +namespace PR8034 { + struct C { + operator int(); + + private: + template <typename T> operator T(); + }; + int x = C().operator int(); +} diff --git a/test/SemaCXX/conversion.cpp b/test/SemaCXX/conversion.cpp index f648943..fdda7ac 100644 --- a/test/SemaCXX/conversion.cpp +++ b/test/SemaCXX/conversion.cpp @@ -43,3 +43,10 @@ namespace test1 { return p == foo(); } } + +namespace test2 { + struct A { + unsigned int x : 2; + A() : x(10) {} // expected-warning {{implicit truncation from 'int' to bitfield changes value from 10 to 2}} + }; +} diff --git a/test/SemaCXX/copy-assignment.cpp b/test/SemaCXX/copy-assignment.cpp index 5730b2a..f3dadc44 100644 --- a/test/SemaCXX/copy-assignment.cpp +++ b/test/SemaCXX/copy-assignment.cpp @@ -99,13 +99,15 @@ void test() { // <rdar://problem/8315440>: Don't crash // FIXME: the recovery here is really bad. -namespace test1 { - template<typename T> class A : public unknown::X { // expected-error {{undeclared identifier 'unknown'}} expected-error {{expected class name}} - A(UndeclaredType n) : X(n) {} // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{undeclared identifier 'n'}} expected-error {{expected ';' at end}} expected-error {{field has incomplete type}} +namespace test1 { // expected-note{{to match this '{'}} + template<typename T> class A : public unknown::X { // expected-error {{undeclared identifier 'unknown'}} expected-error {{expected class name}} \ + // expected-note{{template parameter is declared here}} + A(UndeclaredType n) : X(n) {} // expected-error{{expected ')'}} expected-note{{to match this '('}} \ + // expected-error{{use of undeclared identifier 'n'}} }; - template<typename T> class B : public A<T> { + template<typename T> class B : public A<T> { // expected-error{{declaration of 'T' shadows template parameter}} virtual void foo() {} }; - extern template class A<char>; // expected-note {{in instantiation}} expected-note {{not complete}} - extern template class B<char>; -} + extern template class A<char>; // expected-error{{expected member name or ';' after declaration specifiers}} + extern template class B<char>; // expected-error{{expected member name or ';' after declaration specifiers}} +} // expected-error{{expected ';' after class}} // expected-error{{expected '}'}} diff --git a/test/SemaCXX/copy-initialization.cpp b/test/SemaCXX/copy-initialization.cpp index 0c4aa96..fb83dcf 100644 --- a/test/SemaCXX/copy-initialization.cpp +++ b/test/SemaCXX/copy-initialization.cpp @@ -10,8 +10,8 @@ class Y : public X { }; void f(Y y, int *ip, float *fp) { X x1 = y; // expected-error{{no matching constructor for initialization of 'X'}} - X x2 = 0; // expected-error{{no viable constructor copying variable}} - X x3 = ip; // expected-error{{no viable constructor copying variable}} + X x2 = 0; + X x3 = ip; X x4 = fp; // expected-error{{no viable conversion}} X x2a(0); // expected-error{{call to constructor of 'X' is ambiguous}} X x3a(ip); @@ -19,11 +19,11 @@ void f(Y y, int *ip, float *fp) { } struct foo { - void bar(); + void bar(); // expected-note{{declared here}} }; // PR3600 -void test(const foo *P) { P->bar(); } // expected-error{{cannot initialize object parameter of type 'foo' with an expression of type 'foo const'}} +void test(const foo *P) { P->bar(); } // expected-error{{'bar' not viable: 'this' argument has type 'const foo', but function is not marked const}} namespace PR6757 { struct Foo { @@ -38,7 +38,7 @@ namespace PR6757 { void f(Foo); void g(Foo foo) { - f(Bar()); // expected-error{{no viable constructor copying parameter of type 'PR6757::Foo const'}} + f(Bar()); // expected-error{{no viable constructor copying parameter of type 'const PR6757::Foo'}} f(foo); } } diff --git a/test/SemaCXX/crash-8124080.cpp b/test/SemaCXX/crash-8124080.cpp deleted file mode 100644 index 78a0315..0000000 --- a/test/SemaCXX/crash-8124080.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -// <rdar://problem/8124080> -template<typename _Alloc> class allocator; -template<class _CharT> struct char_traits; -template<typename _CharT, typename _Traits = char_traits<_CharT>, - typename _Alloc = allocator<_CharT> > -class basic_string; -template<typename _CharT, typename _Traits, typename _Alloc> -const typename basic_string<_CharT, _Traits, _Alloc>::size_type -basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_max_size // expected-error{{no member named '_Rep' in 'basic_string<_CharT, _Traits, _Alloc>'}} - = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; - -// PR7118 -template<typename T> -class Foo { - class Bar; - void f() { - Bar i; - } -}; diff --git a/test/SemaCXX/crash-PR7625.cpp b/test/SemaCXX/crash-PR7625.cpp deleted file mode 100644 index 3ddf5e5..0000000 --- a/test/SemaCXX/crash-PR7625.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -template<typename T> struct a : T { - struct x : T { - int aa() { return p; } // expected-error{{use of undeclared identifier 'p'}} - }; -}; diff --git a/test/SemaCXX/crashes.cpp b/test/SemaCXX/crashes.cpp new file mode 100644 index 0000000..c75b040 --- /dev/null +++ b/test/SemaCXX/crashes.cpp @@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// <rdar://problem/8124080> +template<typename _Alloc> class allocator; +template<class _CharT> struct char_traits; +template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > +class basic_string; +template<typename _CharT, typename _Traits, typename _Alloc> +const typename basic_string<_CharT, _Traits, _Alloc>::size_type +basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_max_size // expected-error{{no member named '_Rep' in 'basic_string<_CharT, _Traits, _Alloc>'}} + = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4; + +// PR7118 +template<typename T> +class Foo { + class Bar; + void f() { + Bar i; + } +}; + +// PR7625 +template<typename T> struct a : T { + struct x : T { + int aa() { return p; } // expected-error{{use of undeclared identifier 'p'}} + }; +}; + +// rdar://8605381 +namespace rdar8605381 { +struct X {}; + +struct Y { // expected-note{{candidate}} + Y(); +}; + +struct { + Y obj; +} objs[] = { + new Y // expected-error{{no viable conversion}} +}; +} + +// http://llvm.org/PR8234 +namespace PR8234 { +template<typename Signature> +class callback +{ +}; + +template<typename R , typename ARG_TYPE0> +class callback<R( ARG_TYPE0)> +{ + public: + callback() {} +}; + +template< typename ARG_TYPE0> +class callback<void( ARG_TYPE0)> +{ + public: + callback() {} +}; + +void f() +{ + callback<void(const int&)> op; +} +} + +namespace PR9007 { + struct bar { + enum xxx { + yyy = sizeof(struct foo*) + }; + foo *xxx(); + }; +} + +namespace PR9026 { + class InfallibleTArray { + }; + class Variant; + class CompVariant { + operator const InfallibleTArray&() const; + }; + class Variant { + operator const CompVariant&() const; + }; + void Write(const Variant& __v); + void Write(const InfallibleTArray& __v); + Variant x; + void Write2() { + Write(x); + } +} diff --git a/test/SemaCXX/cstyle-cast.cpp b/test/SemaCXX/cstyle-cast.cpp index ccb25f0..12495ec 100644 --- a/test/SemaCXX/cstyle-cast.cpp +++ b/test/SemaCXX/cstyle-cast.cpp @@ -226,6 +226,6 @@ void memptrs() void (structure::*psf)() = 0; (void)(int (structure::*)())(psf); - (void)(void (structure::*)())(psi); // expected-error {{C-style cast from 'int const structure::*' to 'void (structure::*)()' is not allowed}} + (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}} } diff --git a/test/SemaCXX/dcl_ambig_res.cpp b/test/SemaCXX/dcl_ambig_res.cpp index f0ba297..fa71b11 100644 --- a/test/SemaCXX/dcl_ambig_res.cpp +++ b/test/SemaCXX/dcl_ambig_res.cpp @@ -71,3 +71,6 @@ struct S5 { int foo8() { int v(int(S5::value)); // expected-warning{{disambiguated}} expected-error{{parameter declarator cannot be qualified}} } + +template<typename T> +void rdar8739801( void (T::*)( void ) __attribute__((unused)) ); diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp index 8b28663..2dbd381 100644 --- a/test/SemaCXX/dcl_init_aggr.cpp +++ b/test/SemaCXX/dcl_init_aggr.cpp @@ -120,4 +120,4 @@ u u1 = { 1 }; u u2 = u1; u u3 = 1; // expected-error{{no viable conversion}} u u4 = { 0, "asdf" }; // expected-error{{excess elements in union initializer}} -u u5 = { "asdf" }; // expected-error{{cannot initialize a member subobject of type 'int' with an lvalue of type 'char const [5]'}} +u u5 = { "asdf" }; // expected-error{{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char [5]'}} diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp index 4243c1c..1ddff80 100644 --- a/test/SemaCXX/decl-expr-ambiguity.cpp +++ b/test/SemaCXX/decl-expr-ambiguity.cpp @@ -7,9 +7,9 @@ void f() { // Expressions. T(a)->m = 7; - int(a)++; // expected-error {{expression is not assignable}} - __extension__ int(a)++; // expected-error {{expression is not assignable}} - __typeof(int)(a,5)<<a; // expected-error {{function-style cast to a builtin type can only take one argument}} + int(a)++; // expected-error {{assignment to cast is illegal}} + __extension__ int(a)++; // expected-error {{assignment to cast is illegal}} + __typeof(int)(a,5)<<a; // expected-error {{excess elements in scalar initializer}} void(a), ++a; if (int(a)+1) {} for (int(a)+1;;) {} // expected-warning {{expression result unused}} diff --git a/test/SemaCXX/decl-init-ref.cpp b/test/SemaCXX/decl-init-ref.cpp index 7ae0439..34c4578 100644 --- a/test/SemaCXX/decl-init-ref.cpp +++ b/test/SemaCXX/decl-init-ref.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s -struct A {}; // expected-note {{candidate is the implicit copy constructor}} +struct A {}; struct BASE { operator A(); // expected-note {{candidate function}} @@ -18,10 +18,10 @@ class B : public BASE , public BASE1 extern B f(); -const int& ri = (void)0; // expected-error {{reference to type 'int const' could not bind to an rvalue of type 'void'}} +const int& ri = (void)0; // expected-error {{reference to type 'const int' could not bind to an rvalue of type 'void'}} int main() { - const A& rca = f(); // expected-error {{reference initialization of type 'A const &' with initializer of type 'B' is ambiguous}} + const A& rca = f(); // expected-error {{reference initialization of type 'const A &' with initializer of type 'B' is ambiguous}} A& ra = f(); // expected-error {{non-const lvalue reference to type 'A' cannot bind to a temporary of type 'B'}} } diff --git a/test/SemaCXX/decltype-overloaded-functions.cpp b/test/SemaCXX/decltype-overloaded-functions.cpp index 0aa49b0..c11a47e 100644 --- a/test/SemaCXX/decltype-overloaded-functions.cpp +++ b/test/SemaCXX/decltype-overloaded-functions.cpp @@ -2,10 +2,10 @@ void f(); void f(int); -decltype(f) a; // expected-error{{cannot determine the declared type of an overloaded function}} +decltype(f) a; // expected-error{{cannot resolve overloaded function from context}} template<typename T> struct S { - decltype(T::f) * f; // expected-error{{cannot determine the declared type of an overloaded function}} + decltype(T::f) * f; // expected-error{{cannot resolve overloaded function from context}} }; struct K { void f(); void f(int); }; diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp index d9f1edf..2076322 100644 --- a/test/SemaCXX/default2.cpp +++ b/test/SemaCXX/default2.cpp @@ -68,8 +68,11 @@ struct Y { Nested* self = this, // expected-error{{invalid use of 'this' outside of a nonstatic member function}} int m); // expected-error{{missing default argument on parameter 'm'}} static int c; + Nested(int i = 42); }; + int mem7(Nested n = Nested()); + static int b; }; diff --git a/test/SemaCXX/delete.cpp b/test/SemaCXX/delete.cpp new file mode 100644 index 0000000..4567888 --- /dev/null +++ b/test/SemaCXX/delete.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: cp %s %t +// RUN: %clang_cc1 -fixit -x c++ %t +// RUN: FileCheck -input-file=%t %s + +void f(int a[10][20]) { + // CHECK: delete[] a; + delete a; // expected-warning {{'delete' applied to a pointer-to-array type}} +} diff --git a/test/SemaCXX/deleted-function-extension.cpp b/test/SemaCXX/deleted-function-extension.cpp new file mode 100644 index 0000000..fdf5ac8 --- /dev/null +++ b/test/SemaCXX/deleted-function-extension.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s + +struct A { + A(const A&) = delete; // expected-warning {{deleted function definition accepted as a C++0x extension}} + A& operator=(const A&) = delete; // expected-warning {{deleted function definition accepted as a C++0x extension}} +}; + +void f() = delete; // expected-warning {{deleted function definition accepted as a C++0x extension}} diff --git a/test/SemaCXX/dependent-auto.cpp b/test/SemaCXX/dependent-auto.cpp new file mode 100644 index 0000000..0ea5948 --- /dev/null +++ b/test/SemaCXX/dependent-auto.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x + +template<typename T> +struct only { + only(T); + template<typename U> only(U) = delete; // expected-note {{here}} +}; + +template<typename ...T> +void f(T ...t) { + auto x(t...); // expected-error {{requires an initializer}} expected-error {{contains multiple expressions}} + only<int> check = x; +} + +void g() { + f(); // expected-note {{here}} + f(0); + f(0, 1); // expected-note {{here}} +} + + +template<typename T> +bool h(T t) { + auto a = t; + decltype(a) b; + a = a + b; + + auto p = new auto(t); + + only<double*> test = p; // expected-error {{conversion function from 'char *' to 'only<double *>'}} + return p; +} + +bool b = h('x'); // expected-note {{here}} diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp index cdcae2e..14a4fb8 100644 --- a/test/SemaCXX/destructor.cpp +++ b/test/SemaCXX/destructor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wnon-virtual-dtor -verify %s class A { public: ~A(); @@ -67,7 +67,7 @@ struct Y { namespace PR6421 { class T; // expected-note{{forward declaration}} - class QGenericArgument + class QGenericArgument // expected-note{{declared here}} { template<typename U> void foo(T t) // expected-error{{variable has incomplete type}} @@ -76,7 +76,8 @@ namespace PR6421 { void disconnect() { T* t; - bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} + bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} \ + // expected-error{{does not refer to a value}} } }; } @@ -99,11 +100,11 @@ namespace test6 { T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}} } - virtual ~A() {} // expected-note {{in instantiation of member function 'test6::A<int>::operator delete' requested here}} + virtual ~A() {} }; - class B : A<int> { B(); }; - B::B() {} // expected-note {{in instantiation of member function 'test6::A<int>::~A' requested here}} + class B : A<int> { B(); }; // expected-note {{in instantiation of member function 'test6::A<int>::operator delete' requested here}} + B::B() {} } // Make sure classes are marked invalid when they have invalid @@ -119,3 +120,60 @@ namespace test7 { b->~B(); } } + +namespace nonvirtualdtor { +struct S1 { // expected-warning {{has virtual functions but non-virtual destructor}} + virtual void m(); +}; + +struct S2 { + ~S2(); // expected-warning {{has virtual functions but non-virtual destructor}} + virtual void m(); +}; + +struct S3 : public S1 { // expected-warning {{has virtual functions but non-virtual destructor}} + virtual void m(); +}; + +struct S4 : public S2 { // expected-warning {{has virtual functions but non-virtual destructor}} + virtual void m(); +}; + +struct B { + virtual ~B(); + virtual void m(); +}; + +struct S5 : public B { + virtual void m(); +}; + +struct S6 { + virtual void m(); +private: + ~S6(); +}; + +struct S7 { + virtual void m(); +protected: + ~S7(); +}; + +template<class T> class TS : public B { + virtual void m(); +}; + +TS<int> baz; + +template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' has virtual functions but non-virtual destructor}} + virtual void m(); +}; + +TS2<int> foo; // expected-note {{instantiation}} +} + +namespace PR9238 { + class B { public: ~B(); }; + class C : virtual B { public: ~C() { } }; +} diff --git a/test/SemaCXX/direct-initializer.cpp b/test/SemaCXX/direct-initializer.cpp index 54cd6ca..a7899c7 100644 --- a/test/SemaCXX/direct-initializer.cpp +++ b/test/SemaCXX/direct-initializer.cpp @@ -44,7 +44,7 @@ struct Derived : Base { }; void foo(const Derived cd, Derived d) { - int *pi = cd; // expected-error {{no viable conversion from 'Derived const' to 'int *'}} + int *pi = cd; // expected-error {{no viable conversion from 'const Derived' to 'int *'}} int *ppi = d; } diff --git a/test/SemaCXX/elaborated-type-specifier.cpp b/test/SemaCXX/elaborated-type-specifier.cpp index 2d0b571..760079f 100644 --- a/test/SemaCXX/elaborated-type-specifier.cpp +++ b/test/SemaCXX/elaborated-type-specifier.cpp @@ -35,7 +35,8 @@ namespace NS { } void test_S5_scope() { - S4 *s4; // expected-error{{use of undeclared identifier 'S4'}} + S4 *s4; // expected-error{{use of undeclared identifier 'S4'}} \ + // expected-error{{use of undeclared identifier 's4'}} } int test_funcparam_scope(struct S5 * s5) { diff --git a/test/SemaCXX/enum-bitfield.cpp b/test/SemaCXX/enum-bitfield.cpp new file mode 100644 index 0000000..a766116 --- /dev/null +++ b/test/SemaCXX/enum-bitfield.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++0x -verify -triple x86_64-apple-darwin %s + +enum E {}; + +struct Z {}; +typedef int Integer; + +struct X { + enum E : 1; + enum E : Z; // expected-error{{invalid underlying type}} + enum E2 : int; + enum E3 : Integer; +}; + +struct Y { + enum E : int(2); + enum E : Z(); // expected-error{{not an integer constant}} +}; diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp new file mode 100644 index 0000000..7fdcf0d --- /dev/null +++ b/test/SemaCXX/enum-scoped.cpp @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++0x -verify -triple x86_64-apple-darwin %s + +enum class E1 { + Val1 = 1L +}; + +enum struct E2 { + Val1 = '\0' +}; + +E1 v1 = Val1; // expected-error{{undeclared identifier}} +E1 v2 = E1::Val1; + +static_assert(sizeof(E1) == sizeof(int), "bad size"); +static_assert(sizeof(E1::Val1) == sizeof(int), "bad size"); +static_assert(sizeof(E2) == sizeof(int), "bad size"); +static_assert(sizeof(E2::Val1) == sizeof(int), "bad size"); + +E1 v3 = E2::Val1; // expected-error{{cannot initialize a variable}} +int x1 = E1::Val1; // expected-error{{cannot initialize a variable}} + +enum E3 : char { + Val2 = 1 +}; + +E3 v4 = Val2; +E1 v5 = Val2; // expected-error{{cannot initialize a variable}} + +static_assert(sizeof(E3) == 1, "bad size"); + +int x2 = Val2; + +int a1[Val2]; +int a2[E1::Val1]; // expected-error{{size of array has non-integer type}} + +int* p1 = new int[Val2]; +int* p2 = new int[E1::Val1]; // FIXME Expected-error{{must have integral}} + +enum class E4 { + e1 = -2147483648, // ok + e2 = 2147483647, // ok + e3 = 2147483648 // expected-error{{value is not representable}} +}; + +enum class E5 { + e1 = 2147483647, // ok + e2 // expected-error{{2147483648 is not representable in the underlying}} +}; + +enum class E6 : bool { + e1 = false, e2 = true, + e3 // expected-error{{2 is not representable in the underlying}} +}; + +enum E7 : bool { + e1 = false, e2 = true, + e3 // expected-error{{2 is not representable in the underlying}} +}; + +template <class T> +struct X { + enum E : T { + e1, e2, + e3 // expected-error{{2 is not representable in the underlying}} + }; +}; + +X<bool> X2; // expected-note{{in instantiation of template}} + +enum Incomplete1; // expected-error{{C++ forbids forward references}} + +enum Complete1 : int; +Complete1 complete1; + +enum class Complete2; +Complete2 complete2; + +// 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 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; // 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 : 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 : short; // expected-error{{redeclared with different underlying type}} +enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}} diff --git a/test/SemaCXX/enum.cpp b/test/SemaCXX/enum.cpp index 1dc55e3..b4a050c 100644 --- a/test/SemaCXX/enum.cpp +++ b/test/SemaCXX/enum.cpp @@ -90,3 +90,8 @@ typedef enum { }; // expected-warning{{typedef requires a name}} enum PR7921E { PR7921V = (PR7921E)(123) // expected-error {{expression is not an integer constant expression}} }; + +void PR8089() { + enum E; // expected-error{{ISO C++ forbids forward references to 'enum' types}} + int a = (E)3; // expected-error{{cannot initialize a variable of type 'int' with an rvalue of type 'E'}} +} diff --git a/test/SemaCXX/exceptions.cpp b/test/SemaCXX/exceptions.cpp index 18349d1..bda4a3d 100644 --- a/test/SemaCXX/exceptions.cpp +++ b/test/SemaCXX/exceptions.cpp @@ -1,8 +1,8 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify %s struct A; // expected-note 4 {{forward declaration of 'A'}} -struct Abstract { virtual void f() = 0; }; // expected-note {{pure virtual function 'f'}} +struct Abstract { virtual void f() = 0; }; // expected-note {{unimplemented pure virtual method 'f'}} void trys() { try { @@ -105,7 +105,7 @@ public: void bar () { throw *this; // expected-error{{cannot throw an object of abstract type 'foo'}} } - virtual void test () = 0; // expected-note{{pure virtual function 'test'}} + virtual void test () = 0; // expected-note{{unimplemented pure virtual method 'test'}} }; namespace PR6831 { diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp index b51194a..c4e9dcc 100644 --- a/test/SemaCXX/expressions.cpp +++ b/test/SemaCXX/expressions.cpp @@ -14,3 +14,21 @@ void f0() { register int x; f0_1(&x); } + +namespace test1 { + template <class T> void bar(T &x) { T::fail(); } + template <class T> void bar(volatile T &x) {} + + void test_ints() { + volatile int x; + bar(x = 5); + bar(x += 5); + } + + enum E { E_zero }; + void test_enums() { + volatile E x; + bar(x = E_zero); + bar(x += E_zero); // expected-error {{incompatible type}} + } +} diff --git a/test/SemaCXX/format-attribute.cpp b/test/SemaCXX/format-attribute.cpp deleted file mode 100644 index 92b7cf5..0000000 --- a/test/SemaCXX/format-attribute.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -// PR5521 -struct A { void a(const char*,...) __attribute((format(printf,2,3))); }; -void b(A x) { - x.a("%d", 3); -} -struct X { void a(const char*,...) __attribute((format(printf,1,3))); }; // expected-error {{format argument not a string type}} diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp index 30abcbb..1222dd0 100644 --- a/test/SemaCXX/friend.cpp +++ b/test/SemaCXX/friend.cpp @@ -62,3 +62,71 @@ namespace test4 { class T4B {}; } + +namespace rdar8529993 { +struct A { ~A(); }; // expected-note {{nearly matches}} + +struct B : A +{ + template<int> friend A::~A(); // expected-error {{does not match}} +}; +} + +// PR7915 +namespace test5 { + struct A; + struct A1 { friend void A(); }; + + struct B { friend void B(); }; +} + +// PR8479 +namespace test6_1 { + class A { + public: + private: + friend class vectorA; + A() {} + }; + class vectorA { + public: + vectorA(int i, const A& t = A()) {} + }; + void f() { + vectorA v(1); + } +} +namespace test6_2 { + template<class T> + class vector { + public: + vector(int i, const T& t = T()) {} + }; + class A { + public: + private: + friend class vector<A>; + A() {} + }; + void f() { + vector<A> v(1); + } +} +namespace test6_3 { + template<class T> + class vector { + public: + vector(int i) {} + void f(const T& t = T()) {} + }; + class A { + public: + private: + friend void vector<A>::f(const A&); + A() {} + }; + void f() { + vector<A> v(1); + v.f(); + } +} diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp index 3b08864..61e4da3 100644 --- a/test/SemaCXX/functional-cast.cpp +++ b/test/SemaCXX/functional-cast.cpp @@ -23,7 +23,7 @@ void test_cxx_functional_value_init() { void test_cxx_function_cast_multi() { (void)NoValueInit(0, 0); (void)NoValueInit(0, 0, 0); // expected-error{{no matching constructor for initialization}} - (void)int(1, 2); // expected-error{{function-style cast to a builtin type can only take one argument}} + (void)int(1, 2); // expected-error{{excess elements in scalar initializer}} } @@ -304,7 +304,7 @@ void memptrs() (void)structureimfp(psf); typedef void (structure::*structurevmfp)(); - (void)structurevmfp(psi); // expected-error {{functional-style cast from 'int const structure::*' to 'structurevmfp' (aka 'void (structure::*)()') is not allowed}} + (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}} } @@ -314,4 +314,7 @@ void crash_on_invalid_1() { typedef itn Typo; // expected-error {{unknown type name 'itn'}} (void)Typo(1); // used to crash + + typedef int &int_ref; + (void)int_ref(); // expected-error {{reference to type 'int' requires an initializer}} } diff --git a/test/SemaCXX/gnu-case-ranges.cpp b/test/SemaCXX/gnu-case-ranges.cpp new file mode 100644 index 0000000..c1c18a8 --- /dev/null +++ b/test/SemaCXX/gnu-case-ranges.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -verify %s + +enum E { + one, + two, + three, + four +}; + + +int test(enum E e) +{ + switch (e) + { + case one: + return 7; + case two ... two + 1: + return 42; + case four: + return 25; + default: + return 0; + } +} diff --git a/test/SemaCXX/if-empty-body.cpp b/test/SemaCXX/if-empty-body.cpp new file mode 100644 index 0000000..ec7f89d --- /dev/null +++ b/test/SemaCXX/if-empty-body.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +void f1(int a) { + if (a); // expected-warning {{if statement has empty body}} +} + +void f2(int a) { + if (a) {} +} + +void f3() { + if (1) + xx; // expected-error {{use of undeclared identifier}} + return; // no empty body warning. +} + +// Don't warn about an empty body if is expanded from a macro. +void f4(int i) { + #define BODY(x) + if (i == i) // expected-warning{{self-comparison always evaluates to true}} + BODY(0); + #undef BODY +} + +template <typename T> +void tf() { + #define BODY(x) + if (0) + BODY(0); + #undef BODY +} + +void f5() { + tf<int>(); +} diff --git a/test/SemaCXX/init-priority-attr.cpp b/test/SemaCXX/init-priority-attr.cpp index 6ea263d..7605ee6 100644 --- a/test/SemaCXX/init-priority-attr.cpp +++ b/test/SemaCXX/init-priority-attr.cpp @@ -26,11 +26,11 @@ Two coo[2] __attribute__((init_priority(3))); // expected-error {{init_priority Two koo[4] __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires 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 {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}} -int i __attribute__((init_priority(1001))); // expected-error {{can only use ‘init_priority’ attribute on file-scope definitions of objects of class type}} +int i __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}} int main() { - Two foo __attribute__((init_priority(1001))); // expected-error {{can only use ‘init_priority’ attribute on file-scope definitions of objects of class type}} + Two foo __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/invalid-member-expr.cpp b/test/SemaCXX/invalid-member-expr.cpp index 7307a47..37025d9 100644 --- a/test/SemaCXX/invalid-member-expr.cpp +++ b/test/SemaCXX/invalid-member-expr.cpp @@ -7,8 +7,8 @@ void test() { x.int; // expected-error{{expected unqualified-id}} x.~int(); // expected-error{{expected a class name}} - x.operator; // expected-error{{missing type specifier after 'operator'}} - x.operator typedef; // expected-error{{missing type specifier after 'operator'}} + x.operator; // expected-error{{expected a type}} + x.operator typedef; // expected-error{{expected a type}} } void test2() { @@ -16,8 +16,8 @@ void test2() { x->int; // expected-error{{expected unqualified-id}} x->~int(); // expected-error{{expected a class name}} - x->operator; // expected-error{{missing type specifier after 'operator'}} - x->operator typedef; // expected-error{{missing type specifier after 'operator'}} + x->operator; // expected-error{{expected a type}} + x->operator typedef; // expected-error{{expected a type}} } // PR6327 diff --git a/test/SemaCXX/issue547.cpp b/test/SemaCXX/issue547.cpp new file mode 100644 index 0000000..03c5b7c --- /dev/null +++ b/test/SemaCXX/issue547.cpp @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +template<typename T> +struct classify_function { + static const unsigned value = 0; +}; + +template<typename R, typename ...Args> +struct classify_function<R(Args...)> { + static const unsigned value = 1; +}; + +template<typename R, typename ...Args> +struct classify_function<R(Args...) const> { // expected-warning{{template argument of 'const' qualified function type is a GNU extension}} + static const unsigned value = 2; +}; + +template<typename R, typename ...Args> +struct classify_function<R(Args...) volatile> { // expected-warning{{template argument of 'volatile' qualified function type is a GNU extension}} + static const unsigned value = 3; +}; + +template<typename R, typename ...Args> +struct classify_function<R(Args...) const volatile> { // expected-warning{{template argument of 'const volatile' qualified function type is a GNU extension}} + static const unsigned value = 4; +}; + +template<typename R, typename ...Args> +struct classify_function<R(Args......)> { + static const unsigned value = 5; +}; + +template<typename R, typename ...Args> +struct classify_function<R(Args......) const> { // expected-warning{{template argument of 'const' qualified function type is a GNU extension}} + static const unsigned value = 6; +}; + +template<typename R, typename ...Args> +struct classify_function<R(Args......) volatile> { // expected-warning{{template argument of 'volatile' qualified function type is a GNU extension}} + static const unsigned value = 7; +}; + +template<typename R, typename ...Args> +struct classify_function<R(Args......) const volatile> { // expected-warning{{template argument of 'const volatile' qualified function type is a GNU extension}} + static const unsigned value = 8; +}; + +template<typename R, typename ...Args> +struct classify_function<R(Args......) &&> { // expected-warning{{template argument of '&&' qualified function type is a GNU extension}} + static const unsigned value = 9; +}; + +template<typename R, typename ...Args> +struct classify_function<R(Args......) const &> { // expected-warning{{template argument of 'const &' qualified function type is a GNU extension}} + static const unsigned value = 10; +}; + +typedef void f0(int) const; +typedef void f1(int, float...) const volatile; +typedef void f2(int, double, ...) &&; +typedef void f3(int, double, ...) const &; + +int check0[classify_function<f0>::value == 2? 1 : -1]; +int check1[classify_function<f1>::value == 8? 1 : -1]; +int check2[classify_function<f2>::value == 9? 1 : -1]; +int check3[classify_function<f3>::value == 10? 1 : -1]; diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp index 86c3d3e..b5a10a7 100644 --- a/test/SemaCXX/linkage-spec.cpp +++ b/test/SemaCXX/linkage-spec.cpp @@ -86,3 +86,6 @@ namespace N { } extern "C++" using N::value; + +// PR7076 +extern "C" const char *Version_string = "2.9"; diff --git a/test/SemaCXX/linkage.cpp b/test/SemaCXX/linkage.cpp new file mode 100644 index 0000000..ba56318 --- /dev/null +++ b/test/SemaCXX/linkage.cpp @@ -0,0 +1,68 @@ +// This is an IR generation test because the calculation of visibility +// during IR gen will cause linkage to be implicitly recomputed and +// compared against the earlier cached value. If we had a way of +// testing linkage directly in Sema, that would be better. + +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s + +// PR8926 +namespace test0 { + typedef struct { + void *foo() { return 0; } + } A; + + // CHECK: define linkonce_odr i8* @_ZN5test01A3fooEv( + + void test(A *a) { + a->foo(); + } +} + +namespace test1 { + typedef struct { + template <unsigned n> void *foo() { return 0; } + + void foo() { + foo<0>(); + } + } A; + + // CHECK: define linkonce_odr void @_ZN5test11A3fooEv( + // another at the end + + void test(A *a) { + a->foo(); + } +} + +namespace test2 { + typedef struct { + template <unsigned n> struct B { + void *foo() { return 0; } + }; + + void foo(B<0> *b) { + b->foo(); + } + } A; + + // CHECK: define linkonce_odr void @_ZN5test21A3fooEPNS0_1BILj0EEE( + + void test(A *a) { + a->foo(0); + } +} + +namespace test3 { + namespace { struct A {}; } + + // CHECK: define internal void @_ZN5test34testENS_12_GLOBAL__N_11AE( + void test(A a) {} + void force() { test(A()); } + + // CHECK: define void @test3( + extern "C" void test3(A a) {} +} + +// CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv( +// CHECK: define linkonce_odr i8* @_ZN5test11A3fooILj0EEEPvv( diff --git a/test/SemaCXX/lookup-member.cpp b/test/SemaCXX/lookup-member.cpp new file mode 100644 index 0000000..c75b185 --- /dev/null +++ b/test/SemaCXX/lookup-member.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace A { + class String; +}; + +using A::String; +class String; + +// rdar://8603569 +union value { +char *String; +}; diff --git a/test/SemaCXX/member-expr-anonymous-union.cpp b/test/SemaCXX/member-expr-anonymous-union.cpp index 0f03596..6e35eb2 100644 --- a/test/SemaCXX/member-expr-anonymous-union.cpp +++ b/test/SemaCXX/member-expr-anonymous-union.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify // PR5543 -struct A { int x; union { int* y; float& z; }; }; struct B : A {int a;}; +struct A { int x; union { int* y; float* z; }; }; struct B : A {int a;}; int* a(B* x) { return x->y; } struct x { union { int y; }; }; x y; template <int X> int f() { return X+y.y; } diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp index 953ee48..a4a39d7 100644 --- a/test/SemaCXX/member-expr.cpp +++ b/test/SemaCXX/member-expr.cpp @@ -115,3 +115,18 @@ namespace rdar8231724 { y->N::X1<int>; // expected-error{{'rdar8231724::N::X1' is not a member of class 'rdar8231724::Y'}} } } + +namespace PR9025 { + struct S { int x; }; + S fun(); + int fun(int i); + int g() { + return fun.x; // expected-error{{base of member reference is an overloaded function; perhaps you meant to call the 0-argument overload?}} + } + + S fun2(); // expected-note{{possibly valid overload here}} + S fun2(int i); // expected-note{{possibly valid overload here}} + int g2() { + return fun2.x; // expected-error{{base of member reference is an overloaded function; perhaps you meant to call it?}} + } +} diff --git a/test/SemaCXX/member-operator-expr.cpp b/test/SemaCXX/member-operator-expr.cpp index 5e3d0c0..ae5f8bb 100644 --- a/test/SemaCXX/member-operator-expr.cpp +++ b/test/SemaCXX/member-operator-expr.cpp @@ -14,7 +14,7 @@ void test() { i = x.operator int(); x.operator--(); // expected-error{{no member named 'operator--'}} x.operator float(); // expected-error{{no member named 'operator float'}} - x.operator; // expected-error{{missing type specifier after 'operator'}} + x.operator; // expected-error{{expected a type}} } void test2() { @@ -25,5 +25,5 @@ void test2() { i = x->operator int(); x->operator--(); // expected-error{{no member named 'operator--'}} x->operator float(); // expected-error{{no member named 'operator float'}} - x->operator; // expected-error{{missing type specifier after 'operator'}} + x->operator; // expected-error{{expected a type}} } diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp index 795c0b9..31c651a 100644 --- a/test/SemaCXX/member-pointer.cpp +++ b/test/SemaCXX/member-pointer.cpp @@ -88,7 +88,7 @@ void g() { void (HasMembers::*pmd)() = &HasMembers::d; } -struct Incomplete; // expected-note {{forward declaration}} +struct Incomplete; void h() { HasMembers hm, *phm = &hm; @@ -121,9 +121,10 @@ void h() { (void)(hm.*i); // expected-error {{pointer-to-member}} (void)(phm->*i); // expected-error {{pointer-to-member}} + // Okay Incomplete *inc; int Incomplete::*pii = 0; - (void)(inc->*pii); // expected-error {{pointer into incomplete}} + (void)(inc->*pii); } struct OverloadsPtrMem diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp index 0dc1097..1eb7014 100644 --- a/test/SemaCXX/nested-name-spec.cpp +++ b/test/SemaCXX/nested-name-spec.cpp @@ -244,3 +244,22 @@ namespace PR7133 { return false; } } + +class CLASS { + void CLASS::foo2(); // expected-warning {{extra qualification on member 'foo2'}} +}; + +namespace PR8159 { + class B { }; + + class A { + int A::a; // expected-warning{{extra qualification on member 'a'}} + static int A::b; // expected-warning{{extra qualification on member 'b'}} + int ::c; // expected-error{{non-friend class member 'c' cannot have a qualified name}} + }; +} + +namespace rdar7980179 { + class A { void f0(); }; // expected-note {{previous}} + int A::f0() {} // expected-error {{out-of-line definition of 'rdar7980179::A::f0' differ from the declaration in the return type}} +} diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp index 9a64e4c..13ef461 100644 --- a/test/SemaCXX/new-delete.cpp +++ b/test/SemaCXX/new-delete.cpp @@ -62,8 +62,8 @@ struct abstract { void bad_news(int *ip) { int i = 1; - (void)new; // expected-error {{missing type specifier}} - (void)new 4; // expected-error {{missing type specifier}} + (void)new; // expected-error {{expected a type}} + (void)new 4; // expected-error {{expected a type}} (void)new () int; // expected-error {{expected expression}} (void)new int[1.1]; // expected-error {{array size expression must have integral or enumerated type, not 'double'}} (void)new int[1][i]; // expected-error {{only the first dimension}} @@ -73,7 +73,7 @@ void bad_news(int *ip) (void)new int(1, 2); // expected-error {{excess elements in scalar initializer}} (void)new S(1); // expected-error {{no matching constructor}} (void)new S(1, 1); // expected-error {{call to constructor of 'S' is ambiguous}} - (void)new const int; // expected-error {{default initialization of an object of const type 'int const'}} + (void)new const int; // expected-error {{default initialization of an object of const type 'const int'}} (void)new float*(ip); // expected-error {{cannot initialize a new value of type 'float *' with an lvalue of type 'int *'}} // Undefined, but clang should reject it directly. (void)new int[-1]; // expected-error {{array size is negative}} @@ -234,6 +234,17 @@ void f(X14 *x14a, X14 *x14b) { delete x14a; } +class X15 { +private: + X15(); // expected-note {{declared private here}} + ~X15(); // expected-note {{declared private here}} +}; + +void f(X15* x) { + new X15(); // expected-error {{calling a private constructor}} + delete x; // expected-error {{calling a private destructor}} +} + namespace PR5918 { // Look for template operator new overloads. struct S { template<typename T> static void* operator new(size_t, T); }; void test() { @@ -354,3 +365,27 @@ namespace DeleteParam { void operator delete(void* const); }; } + +// <rdar://problem/8427878> +// Test that the correct 'operator delete' is selected to pair with +// the unexpected placement 'operator new'. +namespace PairedDelete { + template <class T> struct A { + A(); + void *operator new(size_t s, double d = 0); + void operator delete(void *p, double d); + void operator delete(void *p) { + T::dealloc(p); + } + }; + + A<int> *test() { + return new A<int>(); + } +} + +namespace PR7702 { + void test1() { + new DoesNotExist; // expected-error {{expected a type}} + } +} diff --git a/test/SemaCXX/no-exceptions.cpp b/test/SemaCXX/no-exceptions.cpp index 019e25c..f739568 100644 --- a/test/SemaCXX/no-exceptions.cpp +++ b/test/SemaCXX/no-exceptions.cpp @@ -19,3 +19,17 @@ namespace test0 { (void) new Foo(); } } + +namespace test1 { +void f() { + throw; // expected-error {{cannot use 'throw' with exceptions disabled}} +} + +void g() { + try { // expected-error {{cannot use 'try' with exceptions disabled}} + f(); + } catch (...) { + } +} + +} diff --git a/test/SemaCXX/non-empty-class-size-zero.cpp b/test/SemaCXX/non-empty-class-size-zero.cpp new file mode 100644 index 0000000..6b714db --- /dev/null +++ b/test/SemaCXX/non-empty-class-size-zero.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only %s +// rdar://8945175 + +struct X { + int array[0]; + int array1[0]; + int array2[0]; + X(); + ~X(); +}; + +struct Y { + int first; + X padding; + int second; +}; + +int zero_size_array[(sizeof(Y) == 8) -1]; // no error here! diff --git a/test/SemaCXX/nullptr-98.cpp b/test/SemaCXX/nullptr-98.cpp new file mode 100644 index 0000000..0d624c2 --- /dev/null +++ b/test/SemaCXX/nullptr-98.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s +void f(void *); +void g() { f(__nullptr); } diff --git a/test/SemaCXX/nullptr.cpp b/test/SemaCXX/nullptr.cpp index a3aab7f..01f3d93 100644 --- a/test/SemaCXX/nullptr.cpp +++ b/test/SemaCXX/nullptr.cpp @@ -1,8 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s +// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify -std=c++0x -ffreestanding %s #include <stdint.h> -// Don't have decltype yet. -typedef __typeof__(nullptr) nullptr_t; +typedef decltype(nullptr) nullptr_t; struct A {}; @@ -38,11 +37,17 @@ nullptr_t f(nullptr_t null) (void)((void*)0 == nullptr); (void)(null <= (void*)0); (void)((void*)0 <= nullptr); + (void)(0 == nullptr); + (void)(nullptr == 0); + (void)(nullptr <= 0); + (void)(0 <= nullptr); (void)(1 > nullptr); // expected-error {{invalid operands to binary expression}} (void)(1 != nullptr); // expected-error {{invalid operands to binary expression}} (void)(1 + nullptr); // expected-error {{invalid operands to binary expression}} - (void)(0 ? nullptr : 0); // expected-error {{incompatible operand types}} + (void)(0 ? nullptr : 0); // expected-error {{non-pointer operand type 'int' incompatible with nullptr}} (void)(0 ? nullptr : (void*)0); + (void)(0 ? nullptr : A()); // expected-error {{non-pointer operand type 'A' incompatible with nullptr}} + (void)(0 ? A() : nullptr); // expected-error {{non-pointer operand type 'A' incompatible with nullptr}} // Overloading int t = o1(nullptr); @@ -65,3 +70,37 @@ template <int *PI, void (*PF)(), int A::*PM, void (A::*PMF)()> struct T {}; typedef T<nullptr, nullptr, nullptr, nullptr> NT; + +namespace test1 { +template<typename T, typename U> struct is_same { + static const bool value = false; +}; + +template<typename T> struct is_same<T, T> { + static const bool value = true; +}; + +void *g(void*); +bool g(bool); + +// Test that we prefer g(void*) over g(bool). +static_assert(is_same<decltype(g(nullptr)), void*>::value, ""); +} + +namespace test2 { + void f(int, ...) __attribute__((sentinel)); + + void g() { + // nullptr can be used as the sentinel value. + f(10, nullptr); + } +} + +namespace test3 { + void f(const char*, ...) __attribute__((format(printf, 1, 2))); + + void g() { + // Don't warn when using nullptr with %p. + f("%p", nullptr); + } +} diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp index 6bf6965..81a88a3 100644 --- a/test/SemaCXX/overload-call.cpp +++ b/test/SemaCXX/overload-call.cpp @@ -317,8 +317,8 @@ namespace PR5756 { // Tests the exact text used to note the candidates namespace test1 { - template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'char const [6]' to 'unsigned int' for 2nd argument}} - void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'char const [6]' to 'char' for 2nd argument}} + template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}} + void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}} void foo(int n); // expected-note {{candidate function not viable: requires 1 argument, but 2 were provided}} void foo(unsigned n = 10); // expected-note {{candidate function not viable: requires at most 1 argument, but 2 were provided}} void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} @@ -441,7 +441,7 @@ namespace PR6177 { void f(bool const volatile&); // expected-note{{passing argument to parameter here}} void f(String); - void g() { f(""); } // expected-error{{volatile lvalue reference to type 'bool const volatile' cannot bind to a value of unrelated type 'char const [1]'}} + void g() { f(""); } // expected-error{{volatile lvalue reference to type 'const volatile bool' cannot bind to a value of unrelated type 'const char [1]'}} } namespace PR7095 { @@ -490,3 +490,16 @@ namespace NontrivialSubsequence { foo(a); } } + +// rdar://rdar8499524 +namespace rdar8499524 { + struct W {}; + struct S { + S(...); + }; + + void g(const S&); + void f() { + g(W()); + } +} diff --git a/test/SemaCXX/overload-member-call.cpp b/test/SemaCXX/overload-member-call.cpp index 8016b11..37815b9 100644 --- a/test/SemaCXX/overload-member-call.cpp +++ b/test/SemaCXX/overload-member-call.cpp @@ -70,19 +70,19 @@ void test_X2(X2 *x2p, const X2 *cx2p) { // Tests the exact text used to note the candidates namespace test1 { class A { - template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'char const [6]' to 'unsigned int' for 2nd argument}} - void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'char const [6]' to 'char' for 2nd argument}} + template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int] not viable: no known conversion from 'const char [6]' to 'unsigned int' for 2nd argument}} + void foo(int n, char N); // expected-note {{candidate function not viable: no known conversion from 'const char [6]' to 'char' for 2nd argument}} void foo(int n); // expected-note {{candidate function not viable: requires 1 argument, but 2 were provided}} void foo(unsigned n = 10); // expected-note {{candidate function not viable: requires at most 1 argument, but 2 were provided}} void foo(int n, const char *s, int t); // expected-note {{candidate function not viable: requires 3 arguments, but 2 were provided}} void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}} - void bar(double d); //expected-note {{candidate function not viable: 'this' argument has type 'test1::A const', but method is not marked const}} - void bar(int i); //expected-note {{candidate function not viable: 'this' argument has type 'test1::A const', but method is not marked const}} + void bar(double d); //expected-note {{candidate function not viable: 'this' argument has type 'const test1::A', but method is not marked const}} + void bar(int i); //expected-note {{candidate function not viable: 'this' argument has type 'const test1::A', but method is not marked const}} - void baz(A &d); // expected-note {{candidate function not viable: 1st argument ('test1::A const') would lose const qualifier}} - void baz(int i); // expected-note {{candidate function not viable: no known conversion from 'test1::A const' to 'int' for 1st argument}} + void baz(A &d); // expected-note {{candidate function not viable: 1st argument ('const test1::A') would lose const qualifier}} + void baz(int i); // expected-note {{candidate function not viable: no known conversion from 'const test1::A' to 'int' for 1st argument}} }; void test() { diff --git a/test/SemaCXX/overloaded-builtin-operators-0x.cpp b/test/SemaCXX/overloaded-builtin-operators-0x.cpp new file mode 100644 index 0000000..32f1995 --- /dev/null +++ b/test/SemaCXX/overloaded-builtin-operators-0x.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -std=c++0x -verify %s + +template <class T> +struct X +{ + operator T() const {return T();} +}; + +void test_char16t(X<char16_t> x) { + bool b = x == char16_t(); +} diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp index 8a49671..b3c0808 100644 --- a/test/SemaCXX/overloaded-builtin-operators.cpp +++ b/test/SemaCXX/overloaded-builtin-operators.cpp @@ -200,3 +200,40 @@ namespace PR7319 { if (e1 > e2) {} } } + +namespace PR8477 { + struct Foo { + operator bool(); + operator const char *(); + }; + + bool doit() { + Foo foo; + long long zero = 0; + (void)(foo + zero); + (void)(foo - zero); + (void)(zero + foo); + (void)(zero[foo]); + (void)(foo - foo); // expected-error{{use of overloaded operator '-' is ambiguous}} \ + // expected-note 4{{built-in candidate operator-}} \ + // expected-note{{candidates omitted}} + return foo[zero] == zero; + } +} + +namespace PR7851 { + struct X { + operator const void *() const; + operator void *(); + + operator const unsigned *() const; + operator unsigned *(); + }; + + void f() { + X x; + x[0] = 1; + *x = 0; + (void)(x - x); + } +} diff --git a/test/SemaCXX/overloaded-name.cpp b/test/SemaCXX/overloaded-name.cpp new file mode 100644 index 0000000..289d5c9 --- /dev/null +++ b/test/SemaCXX/overloaded-name.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int ovl(int); +float ovl(float); + +template<typename T> T ovl(T); + +void test(bool b) { + (void)((void)0, ovl); // expected-error{{cannot resolve overloaded function from context}} + // PR7863 + (void)(b? ovl : &ovl); // expected-error{{cannot resolve overloaded function from context}} + (void)(b? ovl<float> : &ovl); // expected-error{{cannot resolve overloaded function from context}} + (void)(b? ovl<float> : ovl<float>); +} diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index 24f7f66..4399a02 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -24,7 +24,7 @@ bool operator-(Z, Z); // expected-note{{candidate function}} void g(Y y, Z z) { y = y + z; - bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous; candidates are:}} + bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous}} } struct A { @@ -37,8 +37,8 @@ bool operator==(A&, Z&); // expected-note 2{{candidate function}} void h(A a, const A ac, Z z) { make_A() == z; - a == z; // expected-error{{use of overloaded operator '==' is ambiguous; candidates are:}} - ac == z; // expected-error{{invalid operands to binary expression ('A const' and 'Z')}} + a == z; // expected-error{{use of overloaded operator '==' is ambiguous}} + ac == z; // expected-error{{invalid operands to binary expression ('const A' and 'Z')}} } struct B { @@ -70,11 +70,11 @@ struct E2 { // C++ [over.match.oper]p3 - enum restriction. float& operator==(E1, E2); -void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2) { +void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) { float &f1 = (e1 == e2); float &f2 = (enum1 == e2); float &f3 = (e1 == enum2); - float &f4 = (enum1 == enum2); // expected-error{{non-const lvalue reference to type 'float' cannot bind to a temporary of type 'bool'}} + float &f4 = (enum1 == next_enum1); // expected-error{{non-const lvalue reference to type 'float' cannot bind to a temporary of type 'bool'}} } // PR5244 - Argument-dependent lookup would include the two operators below, diff --git a/test/SemaCXX/pragma-pack.cpp b/test/SemaCXX/pragma-pack.cpp new file mode 100644 index 0000000..1bc738b --- /dev/null +++ b/test/SemaCXX/pragma-pack.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -verify %s + +namespace rdar8745206 { + +struct Base { + int i; +}; + +#pragma pack(push, 1) +struct Sub : public Base { + char c; +}; +#pragma pack(pop) + +int check[sizeof(Sub) == 5 ? 1 : -1]; + +} + +namespace check2 { + +struct Base { + virtual ~Base(); + int x; +}; + +#pragma pack(push, 1) +struct Sub : virtual Base { + char c; +}; +#pragma pack(pop) + +int check[sizeof(Sub) == 13 ? 1 : -1]; + +} diff --git a/test/SemaCXX/pragma-unused.cpp b/test/SemaCXX/pragma-unused.cpp new file mode 100644 index 0000000..c9ddffa --- /dev/null +++ b/test/SemaCXX/pragma-unused.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused-parameter -Wunused -verify %s + +struct S { + void m(int x, int y) { + int z; + #pragma unused(x,y,z) + } +}; diff --git a/test/SemaCXX/ptrtomember-badcall.cpp b/test/SemaCXX/ptrtomember-badcall.cpp deleted file mode 100644 index fb774d8..0000000 --- a/test/SemaCXX/ptrtomember-badcall.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x - -struct S { - int i; - - int mem(int); -}; - -int foo(int S::* ps, S *s) -{ - return (s->*ps)(1); // expected-error {{called object type 'int' is not a function or function pointer}} -} - diff --git a/test/SemaCXX/ptrtomember.cpp b/test/SemaCXX/ptrtomember.cpp new file mode 100644 index 0000000..1038de9 --- /dev/null +++ b/test/SemaCXX/ptrtomember.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x + +struct S { + int i; + + int mem(int); +}; + +int foo(int S::* ps, S *s) +{ + return (s->*ps)(1); // expected-error {{called object type 'int' is not a function or function pointer}} +} + +struct S2 { + int bitfield : 1; +}; + +int S2::*pf = &S2::bitfield; // expected-error {{address of bit-field requested}} + +struct S3 { + void m(); +}; + +void f3(S3* p, void (S3::*m)()) { + p->*m; // expected-error {{a bound member function may only be called}} + (void)(p->*m); // expected-error {{a bound member function may only be called}} + (void)(void*)(p->*m); // expected-error {{a bound member function may only be called}} + (void)reinterpret_cast<void*>(p->*m); // expected-error {{a bound member function may only be called}} + if (p->*m) {} // expected-error {{a bound member function may only be called}} + + p->m; // expected-error {{a bound member function may only be called}} +} diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp index dfb059a..3cd6e18 100644 --- a/test/SemaCXX/qualified-id-lookup.cpp +++ b/test/SemaCXX/qualified-id-lookup.cpp @@ -78,7 +78,7 @@ namespace a { typedef int f2_type(int, int); void test_f2() { - ::f2_type(1, 2); // expected-error {{function-style cast to a builtin type can only take one argument}} + ::f2_type(1, 2); // expected-error {{excess elements in scalar initializer}} } } diff --git a/test/SemaCXX/redeclared-auto.cpp b/test/SemaCXX/redeclared-auto.cpp new file mode 100644 index 0000000..34de54c --- /dev/null +++ b/test/SemaCXX/redeclared-auto.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x + +extern int a; +auto a = 0; // expected-note 2{{here}} +auto a = 0; // expected-error {{redefinition}} +int a = 0; // expected-error {{redefinition}} +extern auto a; // expected-error {{requires an initializer}} + +extern int b; // expected-note {{here}} +auto b = 0.0; // expected-error {{different type}} + +struct S { + static int a; + static int b; // expected-note {{here}} +}; + +auto S::a = 0; // expected-note 2{{here}} +auto S::a; // expected-error {{redefinition}} expected-error {{requires an initializer}} +int S::a = 0; // expected-error {{redefinition}} + +auto S::b = 0.0; // expected-error {{different type}} + +void f() { + extern int a; + extern auto a; // expected-error {{requires an initializer}} +} diff --git a/test/SemaCXX/ref-init-ambiguous.cpp b/test/SemaCXX/ref-init-ambiguous.cpp index a8e95a3..752a348 100644 --- a/test/SemaCXX/ref-init-ambiguous.cpp +++ b/test/SemaCXX/ref-init-ambiguous.cpp @@ -14,15 +14,15 @@ struct C : B, A { }; void test(C c) { - const E2 &e2 = c; // expected-error {{reference initialization of type 'E2 const &' with initializer of type 'C' is ambiguous}} + const E2 &e2 = c; // expected-error {{reference initialization of type 'const E2 &' with initializer of type 'C' is ambiguous}} } void foo(const E2 &);// expected-note{{passing argument to parameter here}} const E2 & re(C c) { - foo(c); // expected-error {{reference initialization of type 'E2 const &' with initializer of type 'C' is ambiguous}} + foo(c); // expected-error {{reference initialization of type 'const E2 &' with initializer of type 'C' is ambiguous}} - return c; // expected-error {{reference initialization of type 'E2 const &' with initializer of type 'C' is ambiguous}} + return c; // expected-error {{reference initialization of type 'const E2 &' with initializer of type 'C' is ambiguous}} } diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp index a7aafe4..ab44e78 100644 --- a/test/SemaCXX/references.cpp +++ b/test/SemaCXX/references.cpp @@ -54,7 +54,7 @@ void test4() { void test5() { // const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0 const volatile int cvi = 1; - const int& r = cvi; // expected-error{{binding of reference to type 'int const' to a value of type 'int const volatile' drops qualifiers}} + const int& r = cvi; // expected-error{{binding of reference to type 'const int' to a value of type 'const volatile int' drops qualifiers}} } // C++ [dcl.init.ref]p3 @@ -130,3 +130,7 @@ namespace PR7149 { X0< const int[1]> c(p1); } } + +namespace PR8608 { + bool& f(unsigned char& c) { return (bool&)c; } +} diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp index f054e52..74dbc01 100644 --- a/test/SemaCXX/reinterpret-cast.cpp +++ b/test/SemaCXX/reinterpret-cast.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding %s #include <stdint.h> @@ -45,9 +45,9 @@ void constness() // Valid: T1* -> T2 const* int const *icp = reinterpret_cast<int const*>(ipppc); // Invalid: T1 const* -> T2* - (void)reinterpret_cast<int*>(icp); // expected-error {{reinterpret_cast from 'int const *' to 'int *' casts away constness}} + (void)reinterpret_cast<int*>(icp); // expected-error {{reinterpret_cast from 'const int *' to 'int *' casts away constness}} // Invalid: T1*** -> T2 const* const** - int const *const **icpcpp = reinterpret_cast<int const* const**>(ipppc); // expected-error {{reinterpret_cast from 'int ***' to 'int const *const **' casts away constness}} + int const *const **icpcpp = reinterpret_cast<int const* const**>(ipppc); // expected-error {{reinterpret_cast from 'int ***' to 'const int *const **' casts away constness}} // Valid: T1* -> T2* int *ip = reinterpret_cast<int*>(icpcpp); // Valid: T* -> T const* @@ -77,12 +77,12 @@ void memptrs() { const int structure::*psi = 0; (void)reinterpret_cast<const float structure::*>(psi); - (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'int const structure::*' to 'int structure::*' casts away constness}} + (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'int structure::*' casts away constness}} void (structure::*psf)() = 0; (void)reinterpret_cast<int (structure::*)()>(psf); - (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'int const structure::*' to 'void (structure::*)()' is not allowed}} + (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}} // Cannot cast from integers to member pointers, not even the null pointer @@ -105,6 +105,6 @@ void const_arrays() { const STRING *s; const char *c; - (void)reinterpret_cast<char *>(s); // expected-error {{reinterpret_cast from 'STRING const *' (aka 'char const (*)[10]') to 'char *' casts away constness}} + (void)reinterpret_cast<char *>(s); // expected-error {{reinterpret_cast from 'const STRING *' (aka 'char const (*)[10]') to 'char *' casts away constness}} (void)reinterpret_cast<const STRING *>(c); } diff --git a/test/SemaCXX/return-noreturn.cpp b/test/SemaCXX/return-noreturn.cpp index dfd5487..7e0a69c 100644 --- a/test/SemaCXX/return-noreturn.cpp +++ b/test/SemaCXX/return-noreturn.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -Wmissing-noreturn -Wno-unreachable-code +// RUN: %clang_cc1 %s -fsyntax-only -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code +// XFAIL: * // A destructor may be marked noreturn and should still influence the CFG. namespace PR6884 { @@ -7,14 +8,11 @@ namespace PR6884 { ~abort_struct() __attribute__((noreturn)); }; - // FIXME: Should either of these actually warn, since the destructor is - // marked noreturn? - int f() { abort_struct(); - } // expected-warning{{control reaches end of non-void function}} + } int f2() { abort_struct s; - } // expected-warning{{control reaches end of non-void function}} + } } diff --git a/test/SemaCXX/return-stack-addr.cpp b/test/SemaCXX/return-stack-addr.cpp index 7d4cb96..fbbaf83 100644 --- a/test/SemaCXX/return-stack-addr.cpp +++ b/test/SemaCXX/return-stack-addr.cpp @@ -119,5 +119,23 @@ struct PR7999_X {}; PR7999_X& PR7999_f(PR7999<PR7999_X> s) { return s.value; } // no-warning void test_PR7999(PR7999_X& x) { (void)PR7999_f(x); } // no-warning +// PR 8774: Don't try to evaluate parameters with default arguments like +// variables with an initializer, especially in templates where the default +// argument may not be an expression (yet). +namespace PR8774 { + template <typename U> struct B { }; + template <typename V> V f(typename B<V>::type const &v = B<V>::value()) { + return v; + } + template <> struct B<const char *> { + typedef const char *type; + static const char *value(); + }; + void g() { + const char *t; + f<const char*>(t); + } +} + // TODO: test case for dynamic_cast. clang does not yet have // support for C++ classes to write such a test case. diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp index 6bdbe52..441c20f 100644 --- a/test/SemaCXX/return.cpp +++ b/test/SemaCXX/return.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fsyntax-only -Wignored-qualifiers -verify +// RUN: %clang_cc1 %s -fexceptions -fsyntax-only -Wignored-qualifiers -verify int test1() { throw; diff --git a/test/SemaCXX/rval-references-examples.cpp b/test/SemaCXX/rval-references-examples.cpp new file mode 100644 index 0000000..f4921a9 --- /dev/null +++ b/test/SemaCXX/rval-references-examples.cpp @@ -0,0 +1,112 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +template<typename T> +class unique_ptr { + T *ptr; + + unique_ptr(const unique_ptr&) = delete; // expected-note 3{{function 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) { } + unique_ptr(unique_ptr &&other) : ptr(other.ptr) { other.ptr = 0; } + explicit unique_ptr(T *ptr) : ptr(ptr) { } + + ~unique_ptr() { delete ptr; } + + unique_ptr &operator=(unique_ptr &&other) { // expected-note{{candidate function not viable: no known conversion from 'unique_ptr<int>' to 'unique_ptr<int> &&' for 1st argument}} + if (this == &other) + return *this; + + delete ptr; + ptr = other.ptr; + other.ptr = 0; + return *this; + } +}; + +template<typename T> +struct remove_reference { + typedef T type; +}; + +template<typename T> +struct remove_reference<T&> { + typedef T type; +}; + +template<typename T> +struct remove_reference<T&&> { + typedef T type; +}; + + +template <class T> typename remove_reference<T>::type&& move(T&& t) { + return static_cast<typename remove_reference<T>::type&&>(t); +} + +template <class T> T&& forward(typename remove_reference<T>::type& t) { + return static_cast<T&&>(t); +} + +template <class T> T&& forward(typename remove_reference<T>::type&& t) { + return static_cast<T&&>(t); +} + +template<typename T, typename ...Args> +unique_ptr<T> make_unique_ptr(Args &&...args) { + return unique_ptr<T>(new T(forward<Args>(args)...)); +} + +template<typename T> void accept_unique_ptr(unique_ptr<T>); // expected-note{{passing argument to parameter here}} + +unique_ptr<int> test_unique_ptr() { + // Simple construction + unique_ptr<int> p; + unique_ptr<int> p1(new int); + + // Move construction + unique_ptr<int> p2(make_unique_ptr<int>(17)); + unique_ptr<int> p3 = make_unique_ptr<int>(17); + + // Copy construction (failures) + unique_ptr<int> p4(p); // expected-error{{call to deleted constructor of 'unique_ptr<int>'}} + unique_ptr<int> p5 = p; // expected-error{{call to deleted constructor of 'unique_ptr<int>'}} + + // Move assignment + p2 = move(p); + p2 = make_unique_ptr<int>(0); + + // Copy assignment (failures); + p2 = p3; // expected-error{{overload resolution selected deleted operator '='}} + + // Implicit copies + accept_unique_ptr(make_unique_ptr<double>(0.0)); + accept_unique_ptr(move(p2)); + + // Implicit copies (failures); + accept_unique_ptr(p); // expected-error{{call to deleted constructor of 'unique_ptr<int>'}} + + return p; +} + +namespace perfect_forwarding { + struct A { }; + + struct F0 { + void operator()(A&, const A&, A&&, const A&&, A&&, const A&&); // expected-note{{candidate function not viable: 5th argument ('const perfect_forwarding::A') would lose const qualifier}} + }; + + template<typename F, typename ...Args> + void forward(F f, Args &&...args) { + f(static_cast<Args&&>(args)...); // expected-error{{no matching function for call to object of type 'perfect_forwarding::F0'}} + } + + template<typename T> T get(); + + void test_forward() { + forward(F0(), get<A&>(), get<A const&>(), get<A>(), get<const A>(), + get<A&&>(), get<const A&&>()); + forward(F0(), get<A&>(), get<A const&>(), get<A>(), get<const A>(), // expected-note{{in instantiation of function template specialization 'perfect_forwarding::forward<perfect_forwarding::F0, perfect_forwarding::A &, const perfect_forwarding::A &, perfect_forwarding::A, const perfect_forwarding::A, const perfect_forwarding::A, const perfect_forwarding::A>' requested here}} + get<const A&&>(), get<const A&&>()); + } +}; diff --git a/test/SemaCXX/rval-references-xfail.cpp b/test/SemaCXX/rval-references-xfail.cpp deleted file mode 100644 index d41f8f1..0000000 --- a/test/SemaCXX/rval-references-xfail.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s -// XFAIL: * -struct MoveOnly { - MoveOnly(); - MoveOnly(const MoveOnly&) = delete; // expected-note {{candidate function}} \ - // expected-note 3{{explicitly marked deleted here}} - MoveOnly(MoveOnly&&); // expected-note {{candidate function}} - MoveOnly(int&&); // expected-note {{candidate function}} -}; - -MoveOnly returning() { - MoveOnly mo; - return mo; -} diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp index 30622cc..11187cb 100644 --- a/test/SemaCXX/rval-references.cpp +++ b/test/SemaCXX/rval-references.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s +// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify -std=c++0x %s typedef int&& irr; typedef irr& ilr_c1; // Collapses to int& @@ -6,7 +6,7 @@ typedef int& ilr; typedef ilr&& ilr_c2; // Collapses to int& irr ret_irr() { - return 0; + return 0; // expected-warning {{returning reference to local temporary}} } struct not_int {}; @@ -28,9 +28,9 @@ fun_type &&make_fun(); void f() { int &&virr1; // expected-error {{declaration of reference variable 'virr1' requires an initializer}} int &&virr2 = 0; - int &&virr3 = virr2; // expected-error {{rvalue reference cannot bind to lvalue}} + int &&virr3 = virr2; // expected-error {{rvalue reference to type 'int' cannot bind to lvalue of type 'int'}} int i1 = 0; - int &&virr4 = i1; // expected-error {{rvalue reference cannot bind to lvalue}} + int &&virr4 = i1; // expected-error {{rvalue reference to type 'int' cannot bind to lvalue of type 'int'}} int &&virr5 = ret_irr(); int &&virr6 = static_cast<int&&>(i1); (void)static_cast<not_int&&>(i1); // expected-error {{types are not compatible}} @@ -47,7 +47,7 @@ void f() { ilr_c2 vilr2 = i1; conv_to_not_int_rvalue cnir; - not_int &&ni4 = cnir; // expected-error {{rvalue reference cannot bind to lvalue}} + not_int &&ni4 = cnir; not_int &ni5 = cnir; // expected-error{{non-const lvalue reference to type 'not_int' cannot bind to a value of unrelated type 'conv_to_not_int_rvalue'}} not_int &&ni6 = conv_to_not_int_rvalue(); diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp index cdc3868..d462af0 100644 --- a/test/SemaCXX/scope-check.cpp +++ b/test/SemaCXX/scope-check.cpp @@ -66,7 +66,7 @@ namespace test4 { C c0; - goto *ip; // expected-warning {{indirect goto might cross protected scopes}} + goto *ip; // expected-error {{indirect goto might cross protected scopes}} C c1; // expected-note {{jump bypasses variable initialization}} lbl1: // expected-note {{possible target of indirect goto}} return 0; @@ -90,7 +90,7 @@ namespace test5 { if (ip[1]) { D d; // expected-note {{jump exits scope of variable with non-trivial destructor}} ip += 2; - goto *ip; // expected-warning {{indirect goto might cross protected scopes}} + goto *ip; // expected-error {{indirect goto might cross protected scopes}} } return 1; } diff --git a/test/SemaCXX/sourceranges.cpp b/test/SemaCXX/sourceranges.cpp new file mode 100644 index 0000000..602d76b --- /dev/null +++ b/test/SemaCXX/sourceranges.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -ast-dump %s | FileCheck %s + +template<class T> +class P { + public: + P(T* t) {} +}; + +namespace foo { +class A {}; +enum B {}; +typedef int C; +} + +int main() { + // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::class A *' + P<foo::A> p14 = new foo::A; + // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::enum B *' + P<foo::B> p24 = new foo::B; + // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::C *' + P<foo::C> pr4 = new foo::C; +} + +foo::A getName() { + // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:10, col:17> 'foo::class A' + return foo::A(); +} diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp index 48f641a..46c6eee 100644 --- a/test/SemaCXX/static-cast.cpp +++ b/test/SemaCXX/static-cast.cpp @@ -55,7 +55,7 @@ void t_529_2() // Bad code below - (void)static_cast<void*>((const int*)0); // expected-error {{static_cast from 'int const *' to 'void *' is not allowed}} + (void)static_cast<void*>((const int*)0); // expected-error {{static_cast from 'const int *' to 'void *' is not allowed}} (void)static_cast<A*>((E*)0); // expected-error {{cannot cast 'E' to its private base class 'A'}} (void)static_cast<A*>((H*)0); // expected-error {{ambiguous conversion}} (void)static_cast<int>((int*)0); // expected-error {{static_cast from 'int *' to 'int' is not allowed}} @@ -84,8 +84,8 @@ void t_529_5_8() (void)static_cast<C1&>(*((A*)0)); // expected-error {{cannot cast 'A' to 'C1 &' via virtual base 'B'}} (void)static_cast<D*>((A*)0); // expected-error {{cannot cast 'A *' to 'D *' via virtual base 'B'}} (void)static_cast<D&>(*((A*)0)); // expected-error {{cannot cast 'A' to 'D &' via virtual base 'B'}} - (void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'A const *' to 'B *' casts away constness}} - (void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'A const' to 'B &' casts away constness}} + (void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'const A *' to 'B *' casts away constness}} + (void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'const A' to 'B &' casts away constness}} (void)static_cast<E*>((A*)0); // expected-error {{cannot cast private base class 'A' to 'E'}} (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast private base class 'A' to 'E'}} (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} @@ -119,7 +119,7 @@ void t_529_10() // Bad code below - (void)static_cast<int*>((const void*)0); // expected-error {{static_cast from 'void const *' to 'int *' casts away constness}} + (void)static_cast<int*>((const void*)0); // expected-error {{static_cast from 'const void *' to 'int *' casts away constness}} (void)static_cast<void (*)()>((void*)0); // expected-error {{static_cast from 'void *' to 'void (*)()' is not allowed}} } @@ -184,7 +184,7 @@ void PR5897() { (void)static_cast<const int(*)[1]>((const void*)0); } namespace PR6072 { struct A { }; - struct B : A { void f(int); void f(); }; + struct B : A { void f(int); void f(); }; // expected-note 2{{candidate function}} struct C : B { }; struct D { }; @@ -192,6 +192,6 @@ namespace PR6072 { (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{{static_cast from '<overloaded function type>' to 'void (PR6072::D::*)()' is not allowed}} + (void)static_cast<void (D::*)()>(&B::f); // expected-error{{address of overloaded function 'f' cannot be static_cast to type 'void (PR6072::D::*)()'}} } } diff --git a/test/SemaCXX/trailing-return-0x.cpp b/test/SemaCXX/trailing-return-0x.cpp new file mode 100644 index 0000000..b52b240 --- /dev/null +++ b/test/SemaCXX/trailing-return-0x.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +template <class T> +struct only +{ + only(T) {} + + template <class U> + only(U) + { + static_assert(sizeof(U) == 0, "expected type failure"); + } +}; + +auto f() -> int +{ + return 0; +} + +auto g(); // expected-error{{return without trailing return type}} + +int h() -> int; // expected-error{{trailing return type must specify return type 'auto', not 'int'}} + +int x; + +template <class T> +auto i(T x) -> decltype(x) +{ + return x; +} + +only<double> p1 = i(1.0); + +template <class T> +struct X +{ + auto f(T x) -> T { return x; } + + template <class U> + auto g(T x, U y) -> decltype(x + y) + { + return x + y; + } + + template<typename U> + struct nested { + template <class V> + auto h(T x, U y, V z) -> decltype(x + y + z) + { + return x + y + z; + } + }; + + template<typename U> + nested<U> get_nested(); +}; + +X<int> xx; +only<int> p2 = xx.f(0L); +only<double> p3 = xx.g(0L, 1.0); +only<double> p4 = xx.get_nested<double>().h(0L, 1.0, 3.14f); diff --git a/test/SemaCXX/type-convert-construct.cpp b/test/SemaCXX/type-convert-construct.cpp index 8f92a03..479af21 100644 --- a/test/SemaCXX/type-convert-construct.cpp +++ b/test/SemaCXX/type-convert-construct.cpp @@ -2,7 +2,7 @@ void f() { float v1 = float(1); - int v2 = typeof(int)(1,2); // expected-error {{function-style cast to a builtin type can only take one argument}} + int v2 = typeof(int)(1,2); // expected-error {{excess elements in scalar initializer}} typedef int arr[]; int v3 = arr(); // expected-error {{array types cannot be value-initialized}} int v4 = int(); diff --git a/test/SemaCXX/type-dependent-exprs.cpp b/test/SemaCXX/type-dependent-exprs.cpp index abe1b4d..398c3cb 100644 --- a/test/SemaCXX/type-dependent-exprs.cpp +++ b/test/SemaCXX/type-dependent-exprs.cpp @@ -22,3 +22,14 @@ T f(T x) { h(1); // expected-error{{use of undeclared identifier 'h'}} return 0; } + +// This one entered into an infinite loop. +template <unsigned long N> +void rdar8520617() { + if (N > 1) { } +} + +int f2() { + rdar8520617<0>(); +} + diff --git a/test/SemaCXX/type-formatting.cpp b/test/SemaCXX/type-formatting.cpp new file mode 100644 index 0000000..3fe9278 --- /dev/null +++ b/test/SemaCXX/type-formatting.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct X0 { }; +struct X1 { }; + +template<typename T> +void f0() { + const T *t = (const X0*)0; // expected-error{{cannot initialize a variable of type 'const X1 *' with an rvalue of type 'const X0 *'}} +} +template void f0<X1>(); // expected-note{{instantiation of}} diff --git a/test/SemaCXX/type-traits-incomplete.cpp b/test/SemaCXX/type-traits-incomplete.cpp index f959821..c0a520e 100644 --- a/test/SemaCXX/type-traits-incomplete.cpp +++ b/test/SemaCXX/type-traits-incomplete.cpp @@ -1,7 +1,8 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -struct S; // expected-note{{forward declaration of 'S'}} +struct S; // expected-note 2 {{forward declaration of 'S'}} void f() { __is_pod(S); // expected-error{{incomplete type 'S' used in type trait expression}} + __is_pod(S[]); // expected-error{{incomplete type 'S' used in type trait expression}} } diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index b05dd07..ff9a6bf 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -11,6 +11,7 @@ struct Empty {}; typedef Empty EmptyAr[10]; typedef int Int; typedef Int IntAr[10]; +typedef Int IntArNB[]; class Statics { static int priv; static NonPOD np; }; union EmptyUnion {}; union Union { int i; float f; }; @@ -19,7 +20,15 @@ struct HasOp { void operator *(); }; struct HasConv { operator int(); }; struct HasAssign { void operator =(int); }; +struct HasAnonymousUnion { + union { + int i; + float f; + }; +}; + // Not PODs +typedef const void cvoid; struct Derives : POD {}; struct DerivesEmpty : Empty {}; struct HasCons { HasCons(int); }; @@ -32,6 +41,7 @@ struct HasNonPOD { NonPOD np; }; struct HasVirt { virtual void Virt() {}; }; typedef Derives NonPODAr[10]; typedef HasVirt VirtAr[10]; +typedef HasCons NonPODArNB[]; union NonPODUnion { int i; Derives n; }; struct HasNoThrowCopyAssign { @@ -80,6 +90,8 @@ void is_pod() int t11[T(__is_pod(HasOp))]; int t12[T(__is_pod(HasConv))]; int t13[T(__is_pod(HasAssign))]; + int t14[T(__is_pod(IntArNB))]; + int t15[T(__is_pod(HasAnonymousUnion))]; int t21[F(__is_pod(Derives))]; int t22[F(__is_pod(HasCons))]; @@ -92,6 +104,9 @@ void is_pod() int t29[F(__is_pod(HasVirt))]; int t30[F(__is_pod(NonPODAr))]; int t31[F(__is_pod(DerivesEmpty))]; + int t32[F(__is_pod(void))]; + int t33[F(__is_pod(cvoid))]; + int t34[F(__is_pod(NonPODArNB))]; // int t32[F(__is_pod(NonPODUnion))]; } @@ -122,6 +137,9 @@ void is_empty() int t25[F(__is_empty(HasRef))]; int t26[F(__is_empty(HasVirt))]; int t27[F(__is_empty(BitOnly))]; + int t28[F(__is_empty(void))]; + int t29[F(__is_empty(IntArNB))]; + int t30[F(__is_empty(HasAnonymousUnion))]; // int t27[F(__is_empty(DerivesVirt))]; } @@ -132,6 +150,7 @@ void is_class() int t01[T(__is_class(Derives))]; int t02[T(__is_class(HasPriv))]; int t03[T(__is_class(ClassType))]; + int t04[T(__is_class(HasAnonymousUnion))]; int t11[F(__is_class(int))]; int t12[F(__is_class(Enum))]; @@ -139,6 +158,8 @@ void is_class() int t14[F(__is_class(IntAr))]; int t15[F(__is_class(NonPODAr))]; int t16[F(__is_class(Union))]; + int t17[F(__is_class(cvoid))]; + int t18[F(__is_class(IntArNB))]; } typedef Union UnionAr[10]; @@ -154,6 +175,9 @@ void is_union() int t13[F(__is_union(Int))]; int t14[F(__is_union(IntAr))]; int t15[F(__is_union(UnionAr))]; + int t16[F(__is_union(cvoid))]; + int t17[F(__is_union(IntArNB))]; + int t18[F(__is_union(HasAnonymousUnion))]; } typedef Enum EnumType; @@ -170,6 +194,9 @@ void is_enum() int t15[F(__is_enum(UnionAr))]; int t16[F(__is_enum(Derives))]; int t17[F(__is_enum(ClassType))]; + int t18[F(__is_enum(cvoid))]; + int t19[F(__is_enum(IntArNB))]; + int t20[F(__is_enum(HasAnonymousUnion))]; } typedef HasVirt Polymorph; @@ -188,6 +215,8 @@ void is_polymorphic() int t16[F(__is_polymorphic(Derives))]; int t17[F(__is_polymorphic(ClassType))]; int t18[F(__is_polymorphic(Enum))]; + int t19[F(__is_polymorphic(cvoid))]; + int t20[F(__is_polymorphic(IntArNB))]; } typedef Int& IntRef; @@ -198,6 +227,13 @@ struct HasCopy { HasCopy(HasCopy& cp); }; +struct HasTemplateCons { + HasVirt Annoying; + + template <typename T> + HasTemplateCons(const T&); +}; + void has_trivial_default_constructor() { int t01[T(__has_trivial_constructor(Int))]; int t02[T(__has_trivial_constructor(IntAr))]; @@ -217,6 +253,9 @@ void has_trivial_default_constructor() { int t16[T(__has_trivial_constructor(const Int))]; int t17[T(__has_trivial_constructor(NonPODAr))]; int t18[F(__has_trivial_constructor(VirtAr))]; + int t19[F(__has_trivial_constructor(void))]; + int t20[F(__has_trivial_constructor(cvoid))]; + int t21[F(__has_trivial_constructor(HasTemplateCons))]; } void has_trivial_copy_constructor() { @@ -238,6 +277,9 @@ void has_trivial_copy_constructor() { int t16[T(__has_trivial_copy(const Int))]; int t17[F(__has_trivial_copy(NonPODAr))]; int t18[F(__has_trivial_copy(VirtAr))]; + int t19[F(__has_trivial_copy(void))]; + int t20[F(__has_trivial_copy(cvoid))]; + int t21[F(__has_trivial_copy(HasTemplateCons))]; } void has_trivial_copy_assignment() { @@ -259,6 +301,8 @@ void has_trivial_copy_assignment() { int t16[F(__has_trivial_assign(const Int))]; int t17[F(__has_trivial_assign(NonPODAr))]; int t18[F(__has_trivial_assign(VirtAr))]; + int t19[F(__has_trivial_assign(void))]; + int t20[F(__has_trivial_assign(cvoid))]; } void has_trivial_destructor() { @@ -280,14 +324,16 @@ void has_trivial_destructor() { int t16[T(__has_trivial_destructor(const Int))]; int t17[T(__has_trivial_destructor(NonPODAr))]; int t18[T(__has_trivial_destructor(VirtAr))]; + int t19[F(__has_trivial_destructor(void))]; + int t20[F(__has_trivial_destructor(cvoid))]; } struct A { ~A() {} }; template<typename> struct B : A { }; void f() { - int t01[T(!__has_trivial_destructor(A))]; - int t02[T(!__has_trivial_destructor(B<int>))]; + int t01[F(__has_trivial_destructor(A))]; + int t02[F(__has_trivial_destructor(B<int>))]; } void has_nothrow_assign() { @@ -309,10 +355,12 @@ void has_nothrow_assign() { int t16[F(__has_nothrow_assign(const Int))]; int t17[F(__has_nothrow_assign(NonPODAr))]; int t18[F(__has_nothrow_assign(VirtAr))]; - int t19[T(__has_nothrow_assign(HasNoThrowCopyAssign))]; int t20[F(__has_nothrow_assign(HasMultipleCopyAssign))]; int t21[T(__has_nothrow_assign(HasMultipleNoThrowCopyAssign))]; + int t22[F(__has_nothrow_assign(void))]; + int t23[F(__has_nothrow_assign(cvoid))]; + int t24[T(__has_nothrow_assign(HasVirtDest))]; } void has_nothrow_copy() { @@ -338,6 +386,10 @@ void has_nothrow_copy() { int t19[T(__has_nothrow_copy(HasNoThrowCopy))]; int t20[F(__has_nothrow_copy(HasMultipleCopy))]; int t21[T(__has_nothrow_copy(HasMultipleNoThrowCopy))]; + int t22[F(__has_nothrow_copy(void))]; + int t23[F(__has_nothrow_copy(cvoid))]; + int t24[T(__has_nothrow_copy(HasVirtDest))]; + int t25[T(__has_nothrow_copy(HasTemplateCons))]; } void has_nothrow_constructor() { @@ -362,6 +414,10 @@ void has_nothrow_constructor() { int t19[T(__has_nothrow_constructor(HasNoThrowConstructor))]; int t20[F(__has_nothrow_constructor(HasNoThrowConstructorWithArgs))]; + int t21[F(__has_nothrow_constructor(void))]; + int t22[F(__has_nothrow_constructor(cvoid))]; + int t23[T(__has_nothrow_constructor(HasVirtDest))]; + int t24[F(__has_nothrow_constructor(HasTemplateCons))]; } void has_virtual_destructor() { @@ -387,4 +443,108 @@ void has_virtual_destructor() { int t19[T(__has_virtual_destructor(HasVirtDest))]; int t20[T(__has_virtual_destructor(DerivedVirtDest))]; int t21[F(__has_virtual_destructor(VirtDestAr))]; + int t22[F(__has_virtual_destructor(void))]; + int t23[F(__has_virtual_destructor(cvoid))]; +} + + +class Base {}; +class Derived : Base {}; +class Derived2a : Derived {}; +class Derived2b : Derived {}; +class Derived3 : virtual Derived2a, virtual Derived2b {}; +template<typename T> struct BaseA { T a; }; +template<typename T> struct DerivedB : BaseA<T> { }; +template<typename T> struct CrazyDerived : T { }; + + +class class_forward; // expected-note {{forward declaration of 'class_forward'}} + +template <typename Base, typename Derived> +void isBaseOfT() { + int t[T(__is_base_of(Base, Derived))]; +}; +template <typename Base, typename Derived> +void isBaseOfF() { + int t[F(__is_base_of(Base, Derived))]; +}; + +template <class T> class DerivedTemp : Base {}; +template <class T> class NonderivedTemp {}; +template <class T> class UndefinedTemp; // expected-note {{declared here}} + +void is_base_of() { + int t01[T(__is_base_of(Base, Derived))]; + int t02[T(__is_base_of(const Base, Derived))]; + int t03[F(__is_base_of(Derived, Base))]; + int t04[F(__is_base_of(Derived, int))]; + int t05[T(__is_base_of(Base, Base))]; + int t06[T(__is_base_of(Base, Derived3))]; + int t07[T(__is_base_of(Derived, Derived3))]; + int t08[T(__is_base_of(Derived2b, Derived3))]; + int t09[T(__is_base_of(Derived2a, Derived3))]; + int t10[T(__is_base_of(BaseA<int>, DerivedB<int>))]; + int t11[F(__is_base_of(DerivedB<int>, BaseA<int>))]; + int t12[T(__is_base_of(Base, CrazyDerived<Base>))]; + int t13[F(__is_base_of(Union, Union))]; + int t14[T(__is_base_of(Empty, Empty))]; + int t15[T(__is_base_of(class_forward, class_forward))]; + int t16[F(__is_base_of(Empty, class_forward))]; // expected-error {{incomplete type 'class_forward' used in type trait expression}} + int t17[F(__is_base_of(Base&, Derived&))]; + int t18[F(__is_base_of(Base[10], Derived[10]))]; + int t19[F(__is_base_of(int, int))]; + int t20[F(__is_base_of(long, int))]; + int t21[T(__is_base_of(Base, DerivedTemp<int>))]; + int t22[F(__is_base_of(Base, NonderivedTemp<int>))]; + int t23[F(__is_base_of(Base, UndefinedTemp<int>))]; // expected-error {{implicit instantiation of undefined template 'UndefinedTemp<int>'}} + + isBaseOfT<Base, Derived>(); + isBaseOfF<Derived, Base>(); + + isBaseOfT<Base, CrazyDerived<Base> >(); + isBaseOfF<CrazyDerived<Base>, Base>(); + + isBaseOfT<BaseA<int>, DerivedB<int> >(); + isBaseOfF<DerivedB<int>, BaseA<int> >(); +} + +struct FromInt { FromInt(int); }; +struct ToInt { operator int(); }; +typedef void Function(); + +void is_convertible_to(); +class PrivateCopy { + PrivateCopy(const PrivateCopy&); + friend void is_convertible_to(); +}; + +template<typename T> +struct X0 { + template<typename U> X0(const X0<U>&); +}; + +void is_convertible_to() { + int t01[T(__is_convertible_to(Int, Int))]; + int t02[F(__is_convertible_to(Int, IntAr))]; + int t03[F(__is_convertible_to(IntAr, IntAr))]; + int t04[T(__is_convertible_to(void, void))]; + int t05[T(__is_convertible_to(cvoid, void))]; + int t06[T(__is_convertible_to(void, cvoid))]; + int t07[T(__is_convertible_to(cvoid, cvoid))]; + int t08[T(__is_convertible_to(int, FromInt))]; + int t09[T(__is_convertible_to(long, FromInt))]; + int t10[T(__is_convertible_to(double, FromInt))]; + int t11[T(__is_convertible_to(const int, FromInt))]; + int t12[T(__is_convertible_to(const int&, FromInt))]; + int t13[T(__is_convertible_to(ToInt, int))]; + int t14[T(__is_convertible_to(ToInt, const int&))]; + int t15[T(__is_convertible_to(ToInt, long))]; + int t16[F(__is_convertible_to(ToInt, int&))]; + int t17[F(__is_convertible_to(ToInt, FromInt))]; + int t18[T(__is_convertible_to(IntAr&, IntAr&))]; + int t19[T(__is_convertible_to(IntAr&, const IntAr&))]; + int t20[F(__is_convertible_to(const IntAr&, IntAr&))]; + int t21[F(__is_convertible_to(Function, Function))]; + int t22[F(__is_convertible_to(PrivateCopy, PrivateCopy))]; + int t23[T(__is_convertible_to(X0<int>, X0<float>))]; } diff --git a/test/SemaCXX/typeid-ref.cpp b/test/SemaCXX/typeid-ref.cpp index da00169..d01fd31 100644 --- a/test/SemaCXX/typeid-ref.cpp +++ b/test/SemaCXX/typeid-ref.cpp @@ -6,7 +6,7 @@ namespace std { struct X { }; void f() { - // CHECK: @_ZTS1X = weak_odr constant - // CHECK: @_ZTI1X = weak_odr constant + // CHECK: @_ZTS1X = linkonce_odr constant + // CHECK: @_ZTI1X = linkonce_odr unnamed_addr constant (void)typeid(X&); } diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp new file mode 100644 index 0000000..bb87ce0 --- /dev/null +++ b/test/SemaCXX/undefined-internal.cpp @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// Make sure we don't produce invalid IR. +// RUN: %clang_cc1 -emit-llvm-only %s + +namespace test1 { + static void foo(); // expected-warning {{function 'test1::foo' has internal linkage but is not defined}} + template <class T> static void bar(); // expected-warning {{function 'test1::bar<int>' has internal linkage but is not defined}} + + void test() { + foo(); // expected-note {{used here}} + bar<int>(); // expected-note {{used here}} + } +} + +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 test() { + foo(); // expected-note {{used here}} + var = 0; // expected-note {{used here}} + bar<int>(); // expected-note {{used here}} + } +} + +namespace test3 { + namespace { + void foo(); + extern int var; + template <class T> void bar(); + } + + void test() { + foo(); + var = 0; + bar<int>(); + } + + namespace { + void foo() {} + int var = 0; + template <class T> void bar() {} + } +} + +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}} + virtual void bar() = 0; + virtual void baz(); // expected-warning {{function 'test4::<anonymous namespace>::A::baz' has internal linkage but is not defined}} + }; + } + + void test(A &a) { + a.foo(); // expected-note {{used here}} + a.bar(); + a.baz(); // expected-note {{used here}} + } + + struct Test : A { + Test() {} // expected-note 2 {{used here}} + }; +} + +// rdar://problem/9014651 +namespace test5 { + namespace { + struct A {}; + } + + 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}} + }; + + void test() { + B<A>::var = 0; // expected-note {{used here}} + B<A>::foo(); // expected-note {{used here}} + } +} diff --git a/test/SemaCXX/uninit-variables.cpp b/test/SemaCXX/uninit-variables.cpp new file mode 100644 index 0000000..2bc7fb3 --- /dev/null +++ b/test/SemaCXX/uninit-variables.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized-experimental -fsyntax-only %s -verify + +int test1_aux(int &x); +int test1() { + int x; + test1_aux(x); + return x; // no-warning +} + +int test2_aux() { + int x; + int &y = x; + return x; // no-warning +} + +// Handle cases where the CFG may constant fold some branches, thus +// mitigating the need for some path-sensitivity in the analysis. +unsigned test3_aux(); +unsigned test3() { + unsigned x = 0; + const bool flag = true; + if (flag && (x = test3_aux()) == 0) { + return x; + } + return x; +} +unsigned test3_b() { + unsigned x ; + const bool flag = true; + if (flag && (x = test3_aux()) == 0) { + x = 1; + } + return x; // no-warning +} +unsigned test3_c() { + unsigned x; // expected-note{{declared here}} expected-note{{add initialization}} + const bool flag = false; + if (flag && (x = test3_aux()) == 0) { + x = 1; + } + return x; // expected-warning{{variable 'x' is possibly uninitialized when used here}} +} + +enum test4_A { + test4_A_a, test_4_A_b +}; +test4_A test4() { + test4_A a; // expected-note{{variable 'a' is declared here}} + return a; // expected-warning{{variable 'a' is possibly uninitialized when used here}} +} + diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp new file mode 100644 index 0000000..26202fb --- /dev/null +++ b/test/SemaCXX/uninitialized.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -Wall -Wuninitialized -verify %s + +// Previously this triggered a warning on the sizeof(fieldB), indicating +// a use of an uninitialized value. +class Rdar8610363_A { + int fieldA; +public: + Rdar8610363_A(int a); +}; +class Rdar8610363_B { + Rdar8610363_A fieldB; +public: + Rdar8610363_B(int b) : fieldB(sizeof(fieldB)) {} // no-warning +}; diff --git a/test/SemaCXX/unreachable-catch-clauses.cpp b/test/SemaCXX/unreachable-catch-clauses.cpp index 9fc4aef..e8158d4 100644 --- a/test/SemaCXX/unreachable-catch-clauses.cpp +++ b/test/SemaCXX/unreachable-catch-clauses.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify %s class BaseEx {}; class Ex1: public BaseEx {}; diff --git a/test/SemaCXX/unreachable-code.cpp b/test/SemaCXX/unreachable-code.cpp index 40d0c00..03d44ab 100644 --- a/test/SemaCXX/unreachable-code.cpp +++ b/test/SemaCXX/unreachable-code.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wunreachable-code -fblocks -verify %s +// RUN: %clang_cc1 -fexceptions -fsyntax-only -Wunreachable-code -fblocks -verify %s int j; void bar() { } diff --git a/test/SemaCXX/unused-with-error.cpp b/test/SemaCXX/unused-with-error.cpp new file mode 100644 index 0000000..5660007 --- /dev/null +++ b/test/SemaCXX/unused-with-error.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused -verify %s + +// Make sure 'unused' warnings are disabled when errors occurred. +static void foo(int *X) { // expected-note {{candidate}} +} +void bar(const int *Y) { + foo(Y); // expected-error {{no matching function for call}} +} diff --git a/test/SemaCXX/using-decl-1.cpp b/test/SemaCXX/using-decl-1.cpp index 30c4cfd..ebe97f6 100644 --- a/test/SemaCXX/using-decl-1.cpp +++ b/test/SemaCXX/using-decl-1.cpp @@ -95,3 +95,26 @@ namespace test1 { foo(p); // expected-error {{no matching function}} } } + +namespace test2 { + namespace ns { int foo; } + template <class T> using ns::foo; // expected-error {{cannot template a using declaration}} + + // PR8022 + struct A { + template <typename T> void f(T); + }; + class B : A { + template <typename T> using A::f<T>; // expected-error {{cannot template a using declaration}} + }; +} + +// PR8756 +namespace foo +{ + class Class1; // expected-note{{forward declaration}} + class Class2 + { + using ::foo::Class1::Function; // expected-error{{incomplete type 'foo::Class1' named in nested name specifier}} + }; +} diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp index 5148ed5..7b4da9d 100644 --- a/test/SemaCXX/using-decl-templates.cpp +++ b/test/SemaCXX/using-decl-templates.cpp @@ -45,3 +45,21 @@ namespace test0 { template struct E<int>; } + +// PR7896 +namespace PR7896 { +template <class T> struct Foo { + int k (float); +}; +struct Baz { + int k (int); +}; +template <class T> struct Bar : public Foo<T>, Baz { + using Foo<T>::k; + using Baz::k; + int foo() { + return k (1.0f); + } +}; +template int Bar<int>::foo(); +} diff --git a/test/SemaCXX/using-directive.cpp b/test/SemaCXX/using-directive.cpp index 162f7fa0..22c6e14 100644 --- a/test/SemaCXX/using-directive.cpp +++ b/test/SemaCXX/using-directive.cpp @@ -126,3 +126,10 @@ void f4() { f2(1); } using namespace std; // expected-warning{{using directive refers to implicitly-defined namespace 'std'}} using namespace ::std; // expected-warning{{using directive refers to implicitly-defined namespace 'std'}} +namespace test1 { + namespace ns { typedef int test1; } + template <class T> using namespace ns; // expected-error {{cannot template a using directive}} + + // Test that we recovered okay. + test1 x; +} diff --git a/test/SemaCXX/vector-casts.cpp b/test/SemaCXX/vector-casts.cpp index 4bb5808..681a07e 100644 --- a/test/SemaCXX/vector-casts.cpp +++ b/test/SemaCXX/vector-casts.cpp @@ -3,7 +3,7 @@ typedef int __v2si __attribute__((__vector_size__(8))); typedef short __v4hi __attribute__((__vector_size__(8))); typedef short __v8hi __attribute__((__vector_size__(16))); -struct S { }; +struct S { }; // expected-note 2 {{candidate constructor}} void f() { __v2si v2si; @@ -23,9 +23,9 @@ void f() { (void)(__v2si)(ll); (void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' to 'S' is not allowed}} - (void)(S)v2si; // expected-error {{C-style cast from '__v2si' to 'S' is not allowed}} + (void)(S)v2si; // expected-error {{no matching conversion for C-style cast from '__v2si' to 'S'}} (void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'S' to '__v2si' is not allowed}} - (void)(__v2si)s; // expected-error {{C-style cast from 'S' to '__v2si' is not allowed}} + (void)(__v2si)s; // expected-error {{cannot convert 'S' to '__v2si' without a conversion operator}} (void)reinterpret_cast<unsigned char>(v2si); // expected-error {{reinterpret_cast from vector '__v2si' to scalar 'unsigned char' of different size}} (void)(unsigned char)v2si; // expected-error {{C-style cast from vector '__v2si' to scalar 'unsigned char' of different size}} diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp index e07531f..23d86d3 100644 --- a/test/SemaCXX/virtual-override.cpp +++ b/test/SemaCXX/virtual-override.cpp @@ -32,7 +32,7 @@ struct a { }; struct b : private a { }; // expected-note{{declared private here}} class A { - virtual a* f(); // expected-note{{overridden virtual function is here}} + virtual a* f(); // FIXME: desired-note{{overridden virtual function is here}} }; class B : A { @@ -86,7 +86,7 @@ class A { class B : A { virtual a* f(); - virtual const a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides (class type 'T6::a const *' is more qualified than class type 'T6::a *'}} + virtual const a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides (class type 'const T6::a *' is more qualified than class type 'T6::a *'}} }; } @@ -121,7 +121,7 @@ namespace T9 { struct a { }; template<typename T> struct b : a { - int a[sizeof(T) ? -1 : -1]; // expected-error {{array size is negative}} + int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}} }; class A { @@ -167,7 +167,7 @@ void test2() { }; struct Foo3 { - virtual void f(int) = 0; // expected-note{{pure virtual function}} + virtual void f(int) = 0; // expected-note{{unimplemented pure virtual method}} }; template<typename T> @@ -276,3 +276,15 @@ namespace T12 { virtual B& f(); // expected-error {{virtual function 'f' has a different return type ('T12::B &') than the function it overrides (which has return type 'T12::A &&')}} }; }; + +namespace PR8168 { + class A { + public: + virtual void foo() {} // expected-note{{overridden virtual function is here}} + }; + + class B : public A { + public: + static void foo() {} // expected-error{{'static' member function 'foo' overrides a virtual function}} + }; +} diff --git a/test/SemaCXX/vtable-instantiation.cc b/test/SemaCXX/vtable-instantiation.cc new file mode 100644 index 0000000..5a13d95 --- /dev/null +++ b/test/SemaCXX/vtable-instantiation.cc @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// PR8640 + +template<class T1> struct C1 { + virtual void c1() { + T1 t1 = 3; // expected-error {{cannot initialize a variable}} + } +}; + +template<class T2> struct C2 { + void c2() { + new C1<T2>(); // expected-note {{in instantiation of member function}} + } +}; + +void f() { + C2<int*> c2; + c2.c2(); // expected-note {{in instantiation of member function}} +} + diff --git a/test/SemaCXX/warn-assignment-condition.cpp b/test/SemaCXX/warn-assignment-condition.cpp index e5a3425..27eedb9 100644 --- a/test/SemaCXX/warn-assignment-condition.cpp +++ b/test/SemaCXX/warn-assignment-condition.cpp @@ -3,6 +3,7 @@ struct A { int foo(); friend A operator+(const A&, const A&); + A operator|=(const A&); operator bool(); }; @@ -95,4 +96,32 @@ void test() { // expected-note{{use '==' to turn this assignment into an equality comparison}} \ // expected-note{{place parentheses around the assignment to silence this warning}} for (; (a = b + b); ) {} + + // Compound assignments. + if (x |= 2) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '!=' to turn this compound assignment into an inequality comparison}} \ + // expected-note{{place parentheses around the assignment to silence this warning}} + + if (a |= b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} \ + // expected-note{{use '!=' to turn this compound assignment into an inequality comparison}} \ + // expected-note{{place parentheses around the assignment to silence this warning}} + + if ((x == 5)) {} // expected-warning {{equality comparison with extraneous parentheses}} \ + // expected-note {{use '=' to turn this equality comparison into an assignment}} \ + // expected-note {{remove extraneous parentheses around the comparison to silence this warning}} + if ((5 == x)) {} + +#define EQ(x,y) ((x) == (y)) + if (EQ(x, 5)) {} +#undef EQ } + +void (*fn)(); + +void test2() { + if ((fn == test2)) {} // expected-warning {{equality comparison with extraneous parentheses}} \ + // expected-note {{use '=' to turn this equality comparison into an assignment}} \ + // expected-note {{remove extraneous parentheses around the comparison to silence this warning}} + if ((test2 == fn)) {} +} + diff --git a/test/SemaCXX/warn-enum-compare.cpp b/test/SemaCXX/warn-enum-compare.cpp new file mode 100644 index 0000000..52639e7 --- /dev/null +++ b/test/SemaCXX/warn-enum-compare.cpp @@ -0,0 +1,212 @@ +// RUN: %clang_cc1 %s -fsyntax-only -verify + +enum Foo { FooA, FooB, FooC }; +enum Bar { BarD, BarE, BarF }; +enum { AnonAA = 42, AnonAB = 43 }; +enum { AnonBA = 44, AnonBB = 45 }; + +namespace name1 { + enum Foo {F1, F2, F3}; + enum Baz {B1, B2, B3}; +} + +namespace name2 { + enum Baz {B1, B2, B3}; +} + +using name1::Baz; +using name1::B1; +using name2::B2; +typedef name1::Foo oneFoo; +typedef name1::Foo twoFoo; +Foo getFoo(); +Bar getBar(); + +void test () { + Foo x = FooA; + Bar y = BarD; + Baz z = name1::B3; + name1::Foo a; + oneFoo b; + twoFoo c; + + while (x == FooA); + while (y == BarD); + while (a == name1::F1); + while (z == name1::B2); + while (a == b); + while (a == c); + while (b == c); + while (B1 == name1::B2); + while (B2 == name2::B1); + while (x == AnonAA); + while (AnonBB == y); + while (AnonAA == AnonAB); + while (AnonAB == AnonBA); + while (AnonBB == AnonAA); + + while ((x) == FooA); + while ((y) == BarD); + while ((a) == name1::F1); + while (z == (name1::B2)); + while (a == (b)); + while (a == (c)); + while ((b) == (c)); + while ((B1) == (name1::B2)); + while ((B2) == (name2::B1)); + + while (((x)) == FooA); + while ((y) == (BarD)); + while ((a) == (name1::F1)); + while (z == (name1::B2)); + while ((a) == ((((b))))); + while (((a)) == (c)); + while ((b) == (((c)))); + while ((((((B1))))) == (((name1::B2)))); + while (B2 == ((((((name2::B1))))))); + + while (B1 == B2); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} + while (name1::B2 == name2::B3); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} + while (z == name2::B2); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} + + while (((((B1)))) == B2); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} + while (name1::B2 == (name2::B3)); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} + while (z == ((((name2::B2))))); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} + + while ((((B1))) == (((B2)))); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} + while ((name1::B2) == (((name2::B3)))); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} + while ((((z))) == (name2::B2)); // expected-warning {{comparison of two values with different enumeration types ('name1::Baz' and 'name2::Baz')}} + + while (x == a); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'name1::Foo')}} + while (x == b); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'oneFoo' (aka 'name1::Foo'))}} + while (x == c); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'twoFoo' (aka 'name1::Foo'))}} + + while (x == y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x != y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x >= y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x <= y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x > y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x < y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + + while (FooB == y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB != y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB >= y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB <= y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB > y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB < y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + + while (FooB == BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB != BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB >= BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB <= BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB > BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB < BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + + while (x == BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x != BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x >= BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x <= BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x > BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x < BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + + while (getFoo() == y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() != y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() >= y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() <= y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() > y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() < y); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + + while (getFoo() == BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() != BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() >= BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() <= BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() > BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() < BarD); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + + while (getFoo() == getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() != getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() >= getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() <= getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() > getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (getFoo() < getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + + while (FooB == getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB != getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB >= getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB <= getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB > getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (FooB < getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + + while (x == getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x != getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x >= getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x <= getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x > getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + while (x < getBar()); // expected-warning {{comparison of two values with different enumeration types ('Foo' and 'Bar')}} + + + + while (y == x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y != x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y >= x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y <= x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y > x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y < x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + + while (y == FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y != FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y >= FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y <= FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y > FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y < FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + + while (BarD == FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD != FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD >= FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD <= FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD > FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD <FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + + while (BarD == x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD != x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD >= x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD <= x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD < x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD > x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + + while (y == getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y != getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y >= getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y <= getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y > getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (y < getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + + while (BarD == getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD != getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD >= getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD <= getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD > getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (BarD < getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + + while (getBar() == getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() != getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() >= getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() <= getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() > getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() < getFoo()); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + + while (getBar() == FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() != FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() >= FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() <= FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() > FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() < FooB); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + + while (getBar() == x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() != x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() >= x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() <= x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() > x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + while (getBar() < x); // expected-warning {{comparison of two values with different enumeration types ('Bar' and 'Foo')}} + +} diff --git a/test/SemaCXX/warn-global-constructors.cpp b/test/SemaCXX/warn-global-constructors.cpp index 107bbe1..ad60954 100644 --- a/test/SemaCXX/warn-global-constructors.cpp +++ b/test/SemaCXX/warn-global-constructors.cpp @@ -25,8 +25,8 @@ namespace test1 { A e = A(A()); A f = A(a); // expected-warning {{global constructor}} A g(a); // expected-warning {{global constructor}} - A h((A())); // expected-warning {{global constructor}} - A i((A(A()))); // expected-warning {{global constructor}} + A h((A())); // elided + A i((A(A()))); // elided } namespace test2 { @@ -72,10 +72,26 @@ namespace test6 { struct A { ~A(); }; void f1() { - static A a; // expected-warning {{global destructor}} + static A a; } void f2() { static A& a = *new A; } +} + +namespace pr8095 { + struct Foo { + int x; + Foo(int x1) : x(x1) {} + }; + void foo() { + static Foo a(0); + } -}
\ No newline at end of file + struct Bar { + ~Bar(); + }; + void bar() { + static Bar b; + } +} diff --git a/test/SemaCXX/warn-large-by-value-copy.cpp b/test/SemaCXX/warn-large-by-value-copy.cpp new file mode 100644 index 0000000..39dbd76 --- /dev/null +++ b/test/SemaCXX/warn-large-by-value-copy.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wlarge-by-value-copy=100 %s + +// rdar://8548050 +namespace rdar8548050 { + +struct S100 { + char x[100]; +}; + +struct S101 { + char x[101]; +}; + +S100 f100(S100 s) { return s; } + +S101 f101(S101 s) { return s; } // expected-warning {{return value of 'f101' is a large (101 bytes) pass-by-value object}} \ + // expected-warning {{'s' is a large (101 bytes) pass-by-value argument}} + +typedef int Arr[200]; +void farr(Arr a) { } + +struct NonPOD { + char x[200]; + virtual void m(); +}; + +NonPOD fNonPOD(NonPOD s) { return s; } + +template <unsigned size> +struct TS { + char x[size]; +}; + +template <unsigned size> +void tf(TS<size> ts) {} // expected-warning {{ts' is a large (300 bytes) pass-by-value argument}} + +void g() { + TS<300> ts; + tf<300>(ts); // expected-note {{instantiation}} +} + +} diff --git a/test/SemaCXX/warn-literal-conversion.cpp b/test/SemaCXX/warn-literal-conversion.cpp new file mode 100644 index 0000000..dab5c01 --- /dev/null +++ b/test/SemaCXX/warn-literal-conversion.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -Wliteral-conversion -verify %s + +void foo(int y); + +// Warn when a literal float or double is assigned or bound to an integer. +void test0() { + // Float + int y0 = 1.2222F; // expected-warning {{implicit conversion turns literal floating-point number into integer}} + int y1 = (1.2222F); // expected-warning {{implicit conversion turns literal floating-point number into integer}} + int y2 = (((1.2222F))); // expected-warning {{implicit conversion turns literal floating-point number into integer}} + int y3 = 12E1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}} + int y4 = 1.2E1F; // expected-warning {{implicit conversion turns literal floating-point number into integer}} + // Double + int y5 = 1.2222; // expected-warning {{implicit conversion turns literal floating-point number into integer}} + int y6 = 12E1; // expected-warning {{implicit conversion turns literal floating-point number into integer}} + int y7 = 1.2E1; // expected-warning {{implicit conversion turns literal floating-point number into integer}} + int y8 = (1.2E1); // expected-warning {{implicit conversion turns literal floating-point number into integer}} + + // Test assignment to an existing variable. + y8 = 2.22F; // expected-warning {{implicit conversion turns literal floating-point number into integer}} + + // Test direct initialization. + int y9(1.23F); // expected-warning {{implicit conversion turns literal floating-point number into integer}} + + // Test passing a literal floating-point value to a function that takes an integer. + foo(1.2F); // expected-warning {{implicit conversion turns literal floating-point number into integer}} + + // FIXME: -Wconversion-literal doesn't catch "-1.2F". + int y10 = -1.2F; + + // -Wconversion-literal does NOT catch const values. + // (-Wconversion DOES catch them.) + static const float sales_tax_rate = .095F; + int z = sales_tax_rate; + foo(sales_tax_rate); + + // Expressions, such as those that indicate rounding-down, should NOT produce warnings. + int x = 24 * 0.5; + int y = (24*60*60) * 0.25; + int pennies = 123.45 * 100; +} diff --git a/test/SemaCXX/warn-missing-noreturn.cpp b/test/SemaCXX/warn-missing-noreturn.cpp index f2f9b2e..4caff66 100644 --- a/test/SemaCXX/warn-missing-noreturn.cpp +++ b/test/SemaCXX/warn-missing-noreturn.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -Wmissing-noreturn +// RUN: %clang_cc1 -fsyntax-only -verify %s -Wmissing-noreturn -Wreturn-type void f() __attribute__((noreturn)); template<typename T> void g(T) { // expected-warning {{function could be attribute 'noreturn'}} @@ -50,3 +50,56 @@ void f_R7880658(R7880658 f, R7880658 l) { // no-warning for (; f != l; ++f) { } } + +namespace test2 { + + bool g(); + void *h() __attribute__((noreturn)); + void *j(); + + struct A { + void *f; + + A() : f(0) { } + A(int) : f(h()) { } // expected-warning {{function could be attribute 'noreturn'}} + A(char) : f(j()) { } + A(bool b) : f(b ? h() : j()) { } + }; +} + +namespace test3 { + struct A { + ~A(); + }; + + struct B { + ~B() { } + + A a; + }; + + struct C : A { + ~C() { } + }; +} + +// <rdar://problem/8875247> - Properly handle CFGs with destructors. +struct rdar8875247 { + ~rdar8875247 (); +}; +void rdar8875247_aux(); + +int rdar8875247_test() { + rdar8875247 f; +} // expected-warning{{control reaches end of non-void function}} + +struct rdar8875247_B { + rdar8875247_B(); + ~rdar8875247_B(); +}; + +rdar8875247_B test_rdar8875247_B() { + rdar8875247_B f; + return f; +} // no-warning + diff --git a/test/SemaCXX/warn-overloaded-virtual.cpp b/test/SemaCXX/warn-overloaded-virtual.cpp new file mode 100644 index 0000000..86b1d23 --- /dev/null +++ b/test/SemaCXX/warn-overloaded-virtual.cpp @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fsyntax-only -Woverloaded-virtual -verify %s + +struct B1 { + virtual void foo(int); // expected-note {{declared here}} + virtual void foo(); // expected-note {{declared here}} +}; + +struct S1 : public B1 { + void foo(float); // expected-warning {{hides overloaded virtual functions}} +}; + +struct S2 : public B1 { + void foo(); // expected-note {{declared here}} +}; + +struct B2 { + virtual void foo(void*); // expected-note {{declared here}} +}; + +struct MS1 : public S2, public B2 { + virtual void foo(int); // expected-warning {{hides overloaded virtual functions}} +}; + +struct B3 { + virtual void foo(int); + virtual void foo(); +}; + +struct S3 : public B3 { + using B3::foo; + void foo(float); +}; + +struct B4 { + virtual void foo(); +}; + +struct S4 : public B4 { + void foo(float); + void foo(); +}; + +namespace PR9182 { +struct Base { + virtual void foo(int); +}; + +void Base::foo(int) { } + +struct Derived : public Base { + virtual void foo(int); + void foo(int, int); +}; +} diff --git a/test/SemaCXX/warn-self-assign.cpp b/test/SemaCXX/warn-self-assign.cpp new file mode 100644 index 0000000..fcdb2ab --- /dev/null +++ b/test/SemaCXX/warn-self-assign.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -fsyntax-only -Wself-assign -verify %s + +void f() { + int a = 42, b = 42; + a = a; // expected-warning{{explicitly assigning}} + b = b; // expected-warning{{explicitly assigning}} + a = b; + b = a = b; + a = a = a; // expected-warning{{explicitly assigning}} + a = b = b = a; +} + +// Dummy type. +struct S {}; + +void false_positives() { +#define OP = +#define LHS a +#define RHS a + int a = 42; + // These shouldn't warn due to the use of the preprocessor. + a OP a; + LHS = a; + a = RHS; + LHS OP RHS; +#undef OP +#undef LHS +#undef RHS + + S s; + s = s; // Not a builtin assignment operator, no warning. + + // Volatile stores aren't side-effect free. + volatile int vol_a; + vol_a = vol_a; + volatile int &vol_a_ref = vol_a; + vol_a_ref = vol_a_ref; +} + +template <typename T> void g() { + T a; + a = a; // May or may not be a builtin assignment operator, no warning. +} +void instantiate() { + g<int>(); + g<S>(); +} diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp index 509c344..3bf9af4 100644 --- a/test/SemaCXX/warn-shadow.cpp +++ b/test/SemaCXX/warn-shadow.cpp @@ -42,3 +42,31 @@ class B : A { int data; static int field; }; + +// rdar://8900456 +namespace rdar8900456 { +struct Foo { + static void Baz(); +private: + int Bar; +}; + +void Foo::Baz() { + double Bar = 12; // Don't warn. +} +} + +// http://llvm.org/PR9160 +namespace PR9160 { +struct V { + V(int); +}; +struct S { + V v; + static void m() { + if (1) { + V v(0); + } + } +}; +} diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp index f5601cd..3c8a429 100644 --- a/test/SemaCXX/warn-unreachable.cpp +++ b/test/SemaCXX/warn-unreachable.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks -Wunreachable-code -Wno-unused-value +// RUN: %clang_cc1 %s -fexceptions -fsyntax-only -verify -fblocks -Wunreachable-code -Wno-unused-value int &halt() __attribute__((noreturn)); int &live(); @@ -39,8 +39,10 @@ void test2() { void test3() { halt() --; // expected-warning {{will never be executed}} - halt() - ? // expected-warning {{will never be executed}} + // FIXME: The unreachable part is just the '?', but really all of this + // code is unreachable and shouldn't be separately reported. + halt() // expected-warning {{will never be executed}} + ? dead() : dead(); live(), float // expected-warning {{will never be executed}} diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp index 75fc6a4..c32acb0 100644 --- a/test/SemaCXX/warn-unused-filescoped.cpp +++ b/test/SemaCXX/warn-unused-filescoped.cpp @@ -54,3 +54,27 @@ namespace { }; template <> int TS2<int>::x; // expected-warning{{unused}} } + +namespace PR8841 { + // Ensure that friends of class templates are considered to have a dependent + // context and not marked unused. + namespace { + template <typename T> struct X { + friend bool operator==(const X&, const X&) { return false; } + }; + } + template <typename T> void template_test(X<T> x) { + (void)(x == x); + } + void test() { + X<int> x; + template_test(x); + } +} + +namespace test4 { + namespace { struct A {}; } + + void test(A a); // expected-warning {{unused function}} + extern "C" void test4(A a); +} diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp index 6992cdc..8ae7d6a 100644 --- a/test/SemaCXX/warn-unused-variables.cpp +++ b/test/SemaCXX/warn-unused-variables.cpp @@ -59,3 +59,9 @@ namespace PR6948 { X<char> str (read_from_file()); // expected-error{{use of undeclared identifier 'read_from_file'}} } } + +void unused_local_static() { + static int x = 0; + static int y = 0; // expected-warning{{unused variable 'y'}} +#pragma unused(x) +} diff --git a/test/SemaCXX/warn_false_to_pointer.cpp b/test/SemaCXX/warn_false_to_pointer.cpp index 3a873d8..fb6f955 100644 --- a/test/SemaCXX/warn_false_to_pointer.cpp +++ b/test/SemaCXX/warn_false_to_pointer.cpp @@ -5,5 +5,6 @@ int* j = false; // expected-warning{{ initialization of pointer of type 'int *' void foo(int* i, int *j=(false)) // expected-warning{{ initialization of pointer of type 'int *' from literal 'false'}} { foo(false); // expected-warning{{ initialization of pointer of type 'int *' from literal 'false'}} + foo((int*)false); } diff --git a/test/SemaCXX/writable-strings-deprecated.cpp b/test/SemaCXX/writable-strings-deprecated.cpp new file mode 100644 index 0000000..c89c882 --- /dev/null +++ b/test/SemaCXX/writable-strings-deprecated.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -Wno-deprecated-writable-strings -verify %s +// rdar://8827606 + +char *fun(void) +{ + return "foo"; +} + +void test(bool b) +{ + ++b; // expected-warning {{incrementing expression of type bool is deprecated}} +} |