diff options
Diffstat (limited to 'test/SemaCXX')
92 files changed, 2714 insertions, 147 deletions
diff --git a/test/SemaCXX/PR5086-ambig-resolution-enum.cpp b/test/SemaCXX/PR5086-ambig-resolution-enum.cpp new file mode 100644 index 000000000000..838bc6f3c716 --- /dev/null +++ b/test/SemaCXX/PR5086-ambig-resolution-enum.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +class C { +public: + enum E { e1=0 }; + const char * fun1(int , enum E) const; + int fun1(unsigned, const char *) const; +}; + +void foo(const C& rc) { + enum {BUFLEN = 128 }; + const char *p = rc.fun1(BUFLEN - 2, C::e1); +} diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp index dc764da5322b..e14304a26fe3 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 {{pure virtual function 'f'}} }; static_assert(__is_abstract(C), "C has a pure virtual function"); @@ -20,7 +20,7 @@ class D : C { static_assert(__is_abstract(D), "D inherits from an abstract class"); class E : D { - virtual void f(); + virtual void f(); }; static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f"); @@ -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 {{allocation of an object of abstract type 'C'}} + t3(C()); // expected-error {{allocation of an object of abstract type 'C'}} } C e1[2]; // expected-error {{variable type 'C' is an abstract class}} @@ -54,17 +54,17 @@ typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract c void t6(Func); class F { - F a() { } // expected-error {{return type 'F' is an abstract class}} + F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}} - class D { - void f(F c); // expected-error {{parameter type 'F' is an abstract class}} - }; + class D { + void f(F c); // expected-error {{parameter type 'F' is an abstract class}} + }; - union U { - void u(F c); // expected-error {{parameter type 'F' is an abstract class}} - }; + union U { + 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 {{pure virtual function 'f'}} }; class Abstract; @@ -72,50 +72,47 @@ class Abstract; void t7(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}} void t8() { - void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}} + void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}} } namespace N { - void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}} +void h(Abstract a); // expected-error {{parameter type 'Abstract' is an abstract class}} } class Abstract { - virtual void f() = 0; // expected-note {{pure virtual function 'f'}} + virtual void f() = 0; // expected-note {{pure virtual function 'f'}} }; // <rdar://problem/6854087> class foo { public: - virtual foo *getFoo() = 0; + virtual foo *getFoo() = 0; }; class bar : public foo { public: - virtual bar *getFoo(); + virtual bar *getFoo(); }; bar x; // <rdar://problem/6902298> -class A -{ +class A { public: - virtual void release() = 0; - virtual void release(int count) = 0; - virtual void retain() = 0; + virtual void release() = 0; + virtual void release(int count) = 0; + virtual void retain() = 0; }; -class B : public A -{ +class B : public A { public: - virtual void release(); - virtual void release(int count); - virtual void retain(); + virtual void release(); + virtual void release(int count); + virtual void retain(); }; -void foo(void) -{ - B b; +void foo(void) { + B b; } struct K { diff --git a/test/SemaCXX/access-control-check.cpp b/test/SemaCXX/access-control-check.cpp new file mode 100644 index 000000000000..fb124a932a12 --- /dev/null +++ b/test/SemaCXX/access-control-check.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -fsyntax-only -faccess-control -verify %s + +class M { + int iM; +}; + +class P { + int iP; + int PPR(); +}; + +class N : M,P { + N() {} + // FIXME. No access violation is reported in method call or member access. + int PR() { return iP + PPR(); } +}; diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp index 9c9f0e19ef3c..80ea02bafd41 100644 --- a/test/SemaCXX/addr-of-overloaded-function.cpp +++ b/test/SemaCXX/addr-of-overloaded-function.cpp @@ -23,7 +23,34 @@ int g1(char); int g2(int); int g2(double); +template<typename T> T g3(T); +int g3(int); +int g3(char); + void g_test() { g(g1); g(g2); // expected-error{{call to 'g' is ambiguous; candidates are:}} + g(g3); } + +template<typename T> T h1(T); +template<typename R, typename A1> R h1(A1); +int h1(char); + +void ha(int (*fp)(int)); +void hb(int (*fp)(double)); + +void h_test() { + ha(h1); + hb(h1); +} + +struct A { }; +void f(void (*)(A *)); + +struct B +{ + void g() { f(d); } + void d(void *); + static void d(A *); +}; diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp new file mode 100644 index 000000000000..94598f0e8ef2 --- /dev/null +++ b/test/SemaCXX/ambig-user-defined-conversions.cpp @@ -0,0 +1,52 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// Test1 +struct BASE { + operator int &(); // expected-note {{candidate function}} +}; +struct BASE1 { + operator int &(); // expected-note {{candidate function}} +}; + +struct B : public BASE, BASE1 { + +}; + +extern B f(); + +B b1; +void func(const int ci, const char cc); // expected-note {{candidate function}} +void func(const char ci, const B b); // expected-note {{candidate function}} +void func(const B b, const int ci); // expected-note {{candidate function}} + +const int Test1() { + func(b1, f()); // expected-error {{call to 'func' is ambiguous}} + return f(); // expected-error {{conversion from 'struct B' to 'int const' is ambiguous}} +} + + +// Test2 +struct E; +struct A { + A (E&); +}; + +struct E { + operator A (); +}; + +struct C { + C (E&); +}; + +void f1(A); // expected-note {{candidate function}} +void f1(C); // expected-note {{candidate function}} + +void Test2() +{ + E b; + f1(b); // expected-error {{call to 'f1' is ambiguous}} + // ambiguous because b -> C via constructor and + // b → A via constructor or conversion function. +} + diff --git a/test/SemaCXX/ambiguous-builtin-unary-operator.cpp b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp new file mode 100644 index 000000000000..042546af6902 --- /dev/null +++ b/test/SemaCXX/ambiguous-builtin-unary-operator.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct A { + operator int&(); +}; + +struct B { + operator long&(); +}; + +struct C : B, A { }; + +void test(C c) { + ++c; // expected-error {{use of overloaded operator '++' is ambiguous}}\ + // expected-note 4 {{built-in candidate operator ++ (}} +} + + diff --git a/test/SemaCXX/arrow-operator.cpp b/test/SemaCXX/arrow-operator.cpp new file mode 100644 index 000000000000..9c46e96afc0b --- /dev/null +++ b/test/SemaCXX/arrow-operator.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct T { + void f(); +}; + +struct A { + T* operator->(); // expected-note{{candidate function}} +}; + +struct B { + T* operator->(); // expected-note{{candidate function}} +}; + +struct C : A, B { +}; + +struct D : A { }; + +void f(C &c, D& d) { + c->f(); // expected-error{{use of overloaded operator '->' is ambiguous}} + d->f(); +}
\ No newline at end of file diff --git a/test/SemaCXX/attr-after-definition.cpp b/test/SemaCXX/attr-after-definition.cpp new file mode 100644 index 000000000000..2ef5acfbc0f1 --- /dev/null +++ b/test/SemaCXX/attr-after-definition.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct X { }; +struct Y { }; + +bool f0(X) { return true; } // expected-note{{definition}} +bool f1(X) { return true; } + +__attribute__ ((__visibility__("hidden"))) bool f0(X); // expected-warning{{attribute}} +__attribute__ ((__visibility__("hidden"))) bool f1(Y); diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp new file mode 100644 index 000000000000..54f8b5b57fcd --- /dev/null +++ b/test/SemaCXX/attr-deprecated.cpp @@ -0,0 +1,66 @@ +// RUN: clang-cc %s -verify -fsyntax-only +class A { + void f() __attribute__((deprecated)); + void g(A* a); + void h(A* a) __attribute__((deprecated)); + + int b __attribute__((deprecated)); +}; + +void A::g(A* a) +{ + f(); // expected-warning{{'f' is deprecated}} + a->f(); // expected-warning{{'f' is deprecated}} + + (void)b; // expected-warning{{'b' is deprecated}} + (void)a->b; // expected-warning{{'b' is deprecated}} +} + +void A::h(A* a) +{ + f(); + a->f(); + + (void)b; + (void)a->b; +} + +struct B { + virtual void f() __attribute__((deprecated)); + void g(); +}; + +void B::g() { + f(); + B::f(); // expected-warning{{'f' is deprecated}} +} + +struct C : B { + virtual void f(); + void g(); +}; + +void C::g() { + f(); + C::f(); + B::f(); // expected-warning{{'f' is deprecated}} +} + +void f(B* b, C *c) { + b->f(); + b->B::f(); // expected-warning{{'f' is deprecated}} + + c->f(); + c->C::f(); + c->B::f(); // expected-warning{{'f' is deprecated}} +} + +struct D { + virtual void f() __attribute__((deprecated)); +}; + +void D::f() { } + +void f(D* d) { + d->f(); +} diff --git a/test/SemaCXX/attr-format.cpp b/test/SemaCXX/attr-format.cpp new file mode 100644 index 000000000000..369099a84800 --- /dev/null +++ b/test/SemaCXX/attr-format.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct S { + static void f(const char*, ...) __attribute__((format(printf, 1, 2))); + + // 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))); +}; diff --git a/test/SemaCXX/auto-cxx0x.cpp b/test/SemaCXX/auto-cxx0x.cpp index 33156ef23d2e..aa92bbe4f1f1 100644 --- a/test/SemaCXX/auto-cxx0x.cpp +++ b/test/SemaCXX/auto-cxx0x.cpp @@ -1,5 +1,5 @@ // RUN: clang-cc -fsyntax-only -verify %s -std=c++0x void f() { - auto int a; // expected-error{{cannot combine with previous 'auto' declaration specifier}} + auto int a; // expected-error{{cannot combine with previous 'auto' declaration specifier}} // expected-error{{declaration of variable 'a' with type 'auto' requires an initializer}} int auto b; // expected-error{{cannot combine with previous 'int' declaration specifier}} } diff --git a/test/SemaCXX/builtin-ptrtomember-ambig.cpp b/test/SemaCXX/builtin-ptrtomember-ambig.cpp new file mode 100644 index 000000000000..7e20af35394b --- /dev/null +++ b/test/SemaCXX/builtin-ptrtomember-ambig.cpp @@ -0,0 +1,24 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct A {}; + +struct R { + operator const A*(); +}; + + +struct B : R { + operator A*(); +}; + +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 40 {{built-in candidate operator ->* ('struct A}} +} + diff --git a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp new file mode 100644 index 000000000000..27ca6dc77897 --- /dev/null +++ b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp @@ -0,0 +1,46 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct A {}; +struct E {}; + +struct R { + operator A*(); + operator E*(); // expected-note{{candidate function}} +}; + + +struct S { + operator A*(); + operator E*(); // expected-note{{candidate function}} +}; + +struct B : R { + operator A*(); +}; + +struct C : B { + +}; + +void foo(C c, int A::* pmf) { + int i = c->*pmf; +} + +struct B1 : R, S { + operator A*(); +}; + +struct C1 : B1 { + +}; + +void foo1(C1 c1, int A::* pmf) { + int i = c1->*pmf; + c1->*pmf = 10; +} + +void foo1(C1 c1, int E::* pmf) { + // FIXME. Error reporting needs much improvement here. + int i = c1->*pmf; // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct C1'}} \ + // expected-note {{because of ambiguity in conversion of 'struct C1' to 'struct E *'}} +} diff --git a/test/SemaCXX/builtin-ptrtomember-overload.cpp b/test/SemaCXX/builtin-ptrtomember-overload.cpp new file mode 100644 index 000000000000..718e981805aa --- /dev/null +++ b/test/SemaCXX/builtin-ptrtomember-overload.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct A {}; + +struct B { + operator A*(); +}; + +struct C : B { + +}; + + +void foo(C c, B b, int A::* pmf) { + int j = c->*pmf; + int i = b->*pmf; +} + diff --git a/test/SemaCXX/c99.cpp b/test/SemaCXX/c99.cpp new file mode 100644 index 000000000000..b0ee056ef379 --- /dev/null +++ b/test/SemaCXX/c99.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +void f0(int i) { + char array[i]; // expected-error{{variable length arrays}} +} + +void f1(int i[static 5]) { // expected-error{{C99}} +} diff --git a/test/SemaCXX/cast-conversion.cpp b/test/SemaCXX/cast-conversion.cpp new file mode 100644 index 000000000000..cbc24aef28d5 --- /dev/null +++ b/test/SemaCXX/cast-conversion.cpp @@ -0,0 +1,21 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +struct R { + R(int); +}; + +struct A { + A(R); +}; + +struct B { + B(A); +}; + +int main () { + B(10); // expected-error {{functional-style cast from 'int' to 'struct B' is not allowed}} + (B)10; // expected-error {{C-style cast from 'int' to 'struct B' is not allowed}} + static_cast<B>(10); // expected-error {{static_cast from 'int' to 'struct B' is not allowed}} \\ + // expected-warning {{expression result unused}} +} + diff --git a/test/SemaCXX/cast-explicit-ctor.cpp b/test/SemaCXX/cast-explicit-ctor.cpp new file mode 100644 index 000000000000..62134ae658db --- /dev/null +++ b/test/SemaCXX/cast-explicit-ctor.cpp @@ -0,0 +1,6 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct B { explicit B(bool); }; +void f() { + (void)(B)true; + (void)B(true); +} diff --git a/test/SemaCXX/class-base-member-init.cpp b/test/SemaCXX/class-base-member-init.cpp index c38c3d3337e7..2092847bc02d 100644 --- a/test/SemaCXX/class-base-member-init.cpp +++ b/test/SemaCXX/class-base-member-init.cpp @@ -7,9 +7,9 @@ public: struct D : S { D() : b1(0), b2(1), b1(0), S(), S() {} // expected-error {{multiple initializations given for non-static member 'b1'}} \ - // expected-note {{previous initialization is here}} \ - // expected-error {{multiple initializations given for base 'class S'}} \ - // expected-note {{previous initialization is here}} + // expected-note {{previous initialization is here}} \ + // expected-error {{multiple initializations given for base 'class S'}} \ + // expected-note {{previous initialization is here}} int b1; int b2; diff --git a/test/SemaCXX/class-layout.cpp b/test/SemaCXX/class-layout.cpp new file mode 100644 index 000000000000..56f41bfbdb93 --- /dev/null +++ b/test/SemaCXX/class-layout.cpp @@ -0,0 +1,49 @@ +// RUN: clang-cc -triple x86_64-unknown-unknown %s -fsyntax-only -verify + +#define SA(n, p) int a##n[(p) ? 1 : -1] + +struct A { + int a; + char b; +}; + +SA(0, sizeof(A) == 8); + +struct B : A { + char c; +}; + +SA(1, sizeof(B) == 12); + +struct C { +// Make fields private so C won't be a POD type. +private: + int a; + char b; +}; + +SA(2, sizeof(C) == 8); + +struct D : C { + char c; +}; + +SA(3, sizeof(D) == 8); + +struct __attribute__((packed)) E { + char b; + int a; +}; + +SA(4, sizeof(E) == 5); + +struct __attribute__((packed)) F : E { + char d; +}; + +SA(5, sizeof(F) == 6); + +struct G { G(); }; +struct H : G { }; + +SA(6, sizeof(H) == 1); diff --git a/test/SemaCXX/class-names.cpp b/test/SemaCXX/class-names.cpp index a5569c0c767b..da9014574d2c 100644 --- a/test/SemaCXX/class-names.cpp +++ b/test/SemaCXX/class-names.cpp @@ -5,7 +5,7 @@ C c; void D(int); -class D {}; // expected-note {{previous use is here}} +class D {}; void foo() { @@ -13,7 +13,7 @@ void foo() class D d; } -class D; +class D; // expected-note {{previous use is here}} enum D; // expected-error {{use of 'D' with tag type that does not match previous declaration}} diff --git a/test/SemaCXX/composite-pointer-type.cpp b/test/SemaCXX/composite-pointer-type.cpp index b4a5c884f755..ebc40c14b743 100644 --- a/test/SemaCXX/composite-pointer-type.cpp +++ b/test/SemaCXX/composite-pointer-type.cpp @@ -25,3 +25,11 @@ void f1(volatile Base *b, Derived1 *d1, const Derived2 *d2) { if (d1 == d2) // expected-error{{comparison of distinct}} return; } + +// PR4691 +int ptrcmp1(void *a, int *b) { + return a < b; +} +int ptrcmp2(long *a, int *b) { + return a < b; // expected-error{{distinct}} +}
\ No newline at end of file diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp index 3f4d7159a0f8..fea3324b5fd5 100644 --- a/test/SemaCXX/conditional-expr.cpp +++ b/test/SemaCXX/conditional-expr.cpp @@ -170,11 +170,13 @@ void test() i1 ? &MixedFields::ci : &MixedFieldsDerived::i; const volatile int (MixedFields::*mp2) = i1 ? &MixedFields::ci : &MixedFields::cvi; - i1 ? &MixedFields::ci : &MixedFields::vi; // expected-error {{incompatible operand types}} + (void)(i1 ? &MixedFields::ci : &MixedFields::vi); // Conversion of primitives does not result in an lvalue. &(i1 ? i1 : d1); // expected-error {{address expression must be an lvalue or a function designator}} - + (void)&(i1 ? flds.b1 : flds.i1); // expected-error {{address of bit-field requested}} + (void)&(i1 ? flds.i1 : flds.b1); // expected-error {{address of bit-field requested}} + // Note the thing that this does not test: since DR446, various situations // *must* create a separate temporary copy of class objects. This can only // be properly tested at runtime, though. diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp index a180d907f1b7..b86a27d66d98 100644 --- a/test/SemaCXX/constructor-initializer.cpp +++ b/test/SemaCXX/constructor-initializer.cpp @@ -1,7 +1,8 @@ -// RUN: clang-cc -fsyntax-only -verify %s +// RUN: clang-cc -Wreorder -fsyntax-only -verify %s class A { int m; A() : A::m(17) { } // expected-error {{member initializer 'm' does not name a non-static data member or base class}} + A(int); }; class B : public A { @@ -26,7 +27,7 @@ public: class E : public D, public B { public: - E() : B(), D() { } // expected-error{{base class initializer 'B' names both a direct base class and an inherited virtual base class}} + E() : B(), D() { } // expected-error{{base class initializer 'class B' names both a direct base class and an inherited virtual base class}} }; @@ -64,7 +65,7 @@ struct S : Y, virtual X { }; struct Z : S { - Z() : S(), X(), E() {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}} + Z() : X(), S(), E() {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}} }; class U { @@ -85,11 +86,39 @@ struct Derived : Base, Base1, virtual V { struct Current : Derived { int Derived; - Current() : Derived(1), ::Derived(), + Current() : Derived(1), ::Derived(), // expected-warning {{member 'Derived' will be initialized after}} \ + // expected-note {{base '::Derived'}} \ + // expected-warning {{base class '::Derived' will be initialized after}} ::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}} Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}} - Derived::V(), + Derived::V(), // expected-note {{base 'Derived::V'}} ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} INT::NonExisting() {} // expected-error {{expected a class or namespace}} \ - // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} + // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}} +}; + + // FIXME. This is bad message! +struct M { // expected-note {{candidate function}} \ + // expected-note {{candidate function}} + M(int i, int j); // expected-note {{candidate function}} \ + // // expected-note {{candidate function}} +}; + +struct N : M { + N() : M(1), // expected-error {{no matching constructor for initialization of 'M'}} + m1(100) { } // expected-error {{no matching constructor for initialization of 'm1'}} + M m1; +}; + +struct P : M { // expected-error {{default constructor for 'struct M' is missing in initialization of base class}} + P() { } + M m; // expected-error {{default constructor for 'struct M' is missing in initialization of member}} +}; + +struct Q { + Q() : f1(1,2), // expected-error {{Too many arguments for member initializer 'f1'}} + pf(0.0) { } // expected-error {{incompatible type passing 'double', expected 'float *'}} + float f1; + + float *pf; }; diff --git a/test/SemaCXX/constructor.cpp b/test/SemaCXX/constructor.cpp index 8f289a2b1e96..5ce595cdcece 100644 --- a/test/SemaCXX/constructor.cpp +++ b/test/SemaCXX/constructor.cpp @@ -58,3 +58,29 @@ void y() { a z; z.b(x); } } + +namespace A { + struct S { + S(); + S(int); + void f1(); + void f2(); + operator int (); + ~S(); + }; +} + +A::S::S() {} + +void A::S::f1() {} + +struct S {}; + +A::S::S(int) {} + +void A::S::f2() {} + +A::S::operator int() { return 1; } + +A::S::~S() {} + diff --git a/test/SemaCXX/conversion-delete-expr.cpp b/test/SemaCXX/conversion-delete-expr.cpp new file mode 100644 index 000000000000..708289c362dc --- /dev/null +++ b/test/SemaCXX/conversion-delete-expr.cpp @@ -0,0 +1,109 @@ +// RUN: clang-cc -fsyntax-only -verify -std=c++0x %s + +// Test1 +struct B { + operator char *(); // expected-note {{candidate function}} +}; + +struct D : B { + operator int *(); // expected-note {{candidate function}} +}; + +void f (D d) +{ + delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct D' to a pointer}} +} + +// Test2 +struct B1 { + operator int *(); +}; + +struct D1 : B1 { + operator int *(); +}; + +void f1 (D1 d) +{ + delete d; +} + +// Test3 +struct B2 { + operator const int *(); // expected-note {{candidate function}} +}; + +struct D2 : B2 { + operator int *(); // expected-note {{candidate function}} +}; + +void f2 (D2 d) +{ + delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct D2' to a pointer}} +} + +// Test4 +struct B3 { + operator const int *(); // expected-note {{candidate function}} +}; + +struct A3 { + operator const int *(); // expected-note {{candidate function}} +}; + +struct D3 : A3, B3 { +}; + +void f3 (D3 d) +{ + delete d; // expected-error {{mbiguous conversion of delete expression of type 'struct D3' to a pointer}} +} + +// Test5 +struct X { + operator int(); + operator int*(); +}; + +void f4(X x) { delete x; delete x; } + +// Test6 +struct X1 { + operator int(); + operator int*(); + template<typename T> operator T*() const; // converts to any pointer! +}; + +void f5(X1 x) { delete x; } // OK. In selecting a conversion to pointer function, template convesions are skipped. + +// Test7 +struct Base { + operator int*(); +}; + +struct Derived : Base { + // not the same function as Base's non-const operator int() + operator int*() const; +}; + +void foo6(const Derived cd, Derived d) { + // overload resolution selects Derived::operator int*() const; + delete cd; + delete d; +} + +// Test8 +struct BB { + template<typename T> operator T*() const; +}; + +struct DD : BB { + template<typename T> operator T*() const; // hides base conversion + operator int *() const; +}; + +void foo7 (DD d) +{ + // OK. In selecting a conversion to pointer function, template convesions are skipped. + delete d; +} diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp index 1ca1e689eab0..6182678e3113 100644 --- a/test/SemaCXX/conversion-function.cpp +++ b/test/SemaCXX/conversion-function.cpp @@ -64,3 +64,32 @@ struct Flip { operator Flop() const; }; Flop flop = Flip(); // expected-error {{cannot initialize 'flop' with an rvalue of type 'struct Flip'}} + +// This tests that we don't add the second conversion declaration to the list of user conversions +struct C { + operator const char *() const; +}; + +C::operator const char*() const { return 0; } + +void f(const C& c) { + const char* v = c; +} + +// Test. Conversion in base class is visible in derived class. +class XB { +public: + operator int(); // expected-note {{candidate function}} +}; + +class Yb : public XB { +public: + operator char(); // expected-note {{candidate function}} +}; + +void f(Yb& a) { + if (a) { } // expected-error {{conversion from 'class Yb' to 'bool' is ambiguous}} + int i = a; // OK. calls XB::operator int(); + char ch = a; // OK. calls Yb::operator char(); +} + diff --git a/test/SemaCXX/copy-assignment.cpp b/test/SemaCXX/copy-assignment.cpp index 6e5012f5a7a1..413e4d193367 100644 --- a/test/SemaCXX/copy-assignment.cpp +++ b/test/SemaCXX/copy-assignment.cpp @@ -11,7 +11,7 @@ struct ConvertibleToConstA { }; struct B { - B& operator=(B&); + B& operator=(B&); // expected-note 4 {{candidate function}} }; struct ConvertibleToB { diff --git a/test/SemaCXX/copy-constructor-error.cpp b/test/SemaCXX/copy-constructor-error.cpp new file mode 100644 index 000000000000..2e42fcc3b1cd --- /dev/null +++ b/test/SemaCXX/copy-constructor-error.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct S { // expected-note {{candidate function}} + S (S); // expected-error {{copy constructor must pass its first argument by reference}} \\ + // expected-note {{candidate function}} +}; + +S f(); + +void g() { + S a( f() ); // expected-error {{call to constructor of 'a' is ambiguous}} +} + diff --git a/test/SemaCXX/cstyle-cast.cpp b/test/SemaCXX/cstyle-cast.cpp new file mode 100644 index 000000000000..9c47df927e7b --- /dev/null +++ b/test/SemaCXX/cstyle-cast.cpp @@ -0,0 +1,231 @@ +// RUN: clang-cc -fsyntax-only -verify -faccess-control %s + +struct A {}; + +// ----------- const_cast -------------- + +typedef char c; +typedef c *cp; +typedef cp *cpp; +typedef cpp *cppp; +typedef cppp &cpppr; +typedef const cppp &cpppcr; +typedef const char cc; +typedef cc *ccp; +typedef volatile ccp ccvp; +typedef ccvp *ccvpp; +typedef const volatile ccvpp ccvpcvp; +typedef ccvpcvp *ccvpcvpp; +typedef int iar[100]; +typedef iar &iarr; +typedef int (*f)(int); + +void t_cc() +{ + ccvpcvpp var = 0; + // Cast away deep consts and volatiles. + char ***var2 = (cppp)(var); + char ***const &var3 = var2; + // Const reference to reference. + char ***&var4 = (cpppr)(var3); + // Drop reference. Intentionally without qualifier change. + char *** var5 = (cppp)(var4); + const int ar[100] = {0}; + // Array decay. Intentionally without qualifier change. + int *pi = (int*)(ar); + f fp = 0; + // Don't misidentify fn** as a function pointer. + f *fpp = (f*)(&fp); + int const A::* const A::*icapcap = 0; + int A::* A::* iapap = (int A::* A::*)(icapcap); +} + +// ----------- static_cast ------------- + +struct B : public A {}; // Single public base. +struct C1 : public virtual B {}; // Single virtual base. +struct C2 : public virtual B {}; +struct D : public C1, public C2 {}; // Diamond +struct E : private A {}; // Single private base. +struct F : public C1 {}; // Single path to B with virtual. +struct G1 : public B {}; +struct G2 : public B {}; +struct H : public G1, public G2 {}; // Ambiguous path to B. + +enum Enum { En1, En2 }; +enum Onom { On1, On2 }; + +struct Co1 { operator int(); }; +struct Co2 { Co2(int); }; +struct Co3 { }; +struct Co4 { Co4(Co3); operator Co3(); }; + +// Explicit implicits +void t_529_2() +{ + int i = 1; + (void)(float)(i); + double d = 1.0; + (void)(float)(d); + (void)(int)(d); + (void)(char)(i); + (void)(unsigned long)(i); + (void)(int)(En1); + (void)(double)(En1); + (void)(int&)(i); + (void)(const int&)(i); + + int ar[1]; + (void)(const int*)(ar); + (void)(void (*)())(t_529_2); + + (void)(void*)(0); + (void)(void*)((int*)0); + (void)(volatile const void*)((const int*)0); + (void)(A*)((B*)0); + (void)(A&)(*((B*)0)); + (void)(const B*)((C1*)0); + (void)(B&)(*((C1*)0)); + (void)(A*)((D*)0); + (void)(const A&)(*((D*)0)); + (void)(int B::*)((int A::*)0); + (void)(void (B::*)())((void (A::*)())0); + (void)(A*)((E*)0); // C-style cast ignores access control + (void)(void*)((const int*)0); // const_cast appended + + (void)(int)(Co1()); + (void)(Co2)(1); + (void)(Co3)((Co4)(Co3())); + + // Bad code below + //(void)(A*)((H*)0); // {{static_cast from 'struct H *' to 'struct A *' is not allowed}} +} + +// Anything to void +void t_529_4() +{ + (void)(1); + (void)(t_529_4); +} + +// Static downcasts +void t_529_5_8() +{ + (void)(B*)((A*)0); + (void)(B&)(*((A*)0)); + (void)(const G1*)((A*)0); + (void)(const G1&)(*((A*)0)); + (void)(B*)((const A*)0); // const_cast appended + (void)(B&)(*((const A*)0)); // const_cast appended + (void)(E*)((A*)0); // access control ignored + (void)(E&)(*((A*)0)); // access control ignored + + // Bad code below + + (void)(C1*)((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct C1 *' via virtual base 'struct B'}} + (void)(C1&)(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct C1 &' via virtual base 'struct B'}} + (void)(D*)((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct D *' via virtual base 'struct B'}} + (void)(D&)(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}} + (void)(H*)((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + (void)(H&)(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + + // TODO: Test DR427. This requires user-defined conversions, though. +} + +// Enum conversions +void t_529_7() +{ + (void)(Enum)(1); + (void)(Enum)(1.0); + (void)(Onom)(En1); + + // Bad code below + + (void)(Enum)((int*)0); // expected-error {{C-style cast from 'int *' to 'enum Enum' is not allowed}} +} + +// Void pointer to object pointer +void t_529_10() +{ + (void)(int*)((void*)0); + (void)(const A*)((void*)0); + (void)(int*)((const void*)0); // const_cast appended +} + +// Member pointer upcast. +void t_529_9() +{ + (void)(int A::*)((int B::*)0); + + // Bad code below + (void)(int A::*)((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}} + (void)(int A::*)((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}} +} + +// -------- reinterpret_cast ----------- + +enum test { testval = 1 }; +struct structure { int m; }; +typedef void (*fnptr)(); + +// Test conversion between pointer and integral types, as in p3 and p4. +void integral_conversion() +{ + void *vp = (void*)(testval); + long l = (long)(vp); + (void)(float*)(l); + fnptr fnp = (fnptr)(l); + (void)(char)(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}} + (void)(long)(fnp); +} + +void pointer_conversion() +{ + int *p1 = 0; + float *p2 = (float*)(p1); + structure *p3 = (structure*)(p2); + typedef int **ppint; + ppint *deep = (ppint*)(p3); + (void)(fnptr*)(deep); +} + +void constness() +{ + int ***const ipppc = 0; + int const *icp = (int const*)(ipppc); + (void)(int*)(icp); // const_cast appended + int const *const **icpcpp = (int const* const**)(ipppc); // const_cast appended + int *ip = (int*)(icpcpp); + (void)(int const*)(ip); + (void)(int const* const* const*)(ipppc); +} + +void fnptrs() +{ + typedef int (*fnptr2)(int); + fnptr fp = 0; + (void)(fnptr2)(fp); + void *vp = (void*)(fp); + (void)(fnptr)(vp); +} + +void refs() +{ + long l = 0; + char &c = (char&)(l); + // Bad: from rvalue + (void)(int&)(&c); // expected-error {{C-style cast from rvalue to reference type 'int &'}} +} + +void memptrs() +{ + const int structure::*psi = 0; + (void)(const float structure::*)(psi); + (void)(int structure::*)(psi); // const_cast appended + + void (structure::*psf)() = 0; + (void)(int (structure::*)())(psf); + + (void)(void (structure::*)())(psi); // expected-error {{C-style cast from 'int const struct structure::*' to 'void (struct structure::*)()' is not allowed}} + (void)(int structure::*)(psf); // expected-error {{C-style cast from 'void (struct structure::*)()' to 'int struct structure::*' is not allowed}} +} diff --git a/test/SemaCXX/dcl_ambig_res.cpp b/test/SemaCXX/dcl_ambig_res.cpp index 57bf4095afd0..495a6e6e42c8 100644 --- a/test/SemaCXX/dcl_ambig_res.cpp +++ b/test/SemaCXX/dcl_ambig_res.cpp @@ -50,7 +50,7 @@ void foo5() void foo6() { (void)(int(1)); //expression - (void)(int())1; // expected-error{{used type}} + (void)(int())1; // expected-error{{to 'int ()'}} } // [dcl.ambig.res]p7: @@ -64,3 +64,10 @@ void foo7() { void h7(int *(C7[10])) { } // expected-note{{previous}} void h7(int *(*_fp)(C7 _parm[10])) { } // expected-error{{redefinition}} + +struct S5 { + static bool const value = false; +}; +int foo8() { + int v(int(S5::value)); // expected-warning{{disambiguated}} expected-error{{parameter declarator cannot be qualified}} +} diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp index 10c15ccc9061..20b787a22526 100644 --- a/test/SemaCXX/dcl_init_aggr.cpp +++ b/test/SemaCXX/dcl_init_aggr.cpp @@ -40,8 +40,8 @@ char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-error{{excess elements in ar struct TooFew { int a; char* b; int c; }; TooFew too_few = { 1, "asdf" }; // okay -struct NoDefaultConstructor { // expected-note 5 {{candidate function}} - NoDefaultConstructor(int); // expected-note 5 {{candidate function}} +struct NoDefaultConstructor { // expected-note 3 {{candidate function}} + NoDefaultConstructor(int); // expected-note 3 {{candidate function}} }; struct TooFewError { int a; @@ -53,7 +53,7 @@ TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}} TooFewError too_few_okay2[2] = { 1, 1 }; TooFewError too_few_error2[2] = { 1 }; // expected-error{{no matching constructor}} -NoDefaultConstructor too_few_error3[3] = { }; // expected-error 3 {{no matching constructor}} +NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}} // C++ [dcl.init.aggr]p8 struct Empty { }; diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp index 05e25e9bb868..8d34a9ee7df9 100644 --- a/test/SemaCXX/decl-expr-ambiguity.cpp +++ b/test/SemaCXX/decl-expr-ambiguity.cpp @@ -12,14 +12,14 @@ void f() { __typeof(int)(a,5)<<a; // expected-error {{function-style cast to a builtin type can only take one argument}} void(a), ++a; // expected-warning {{expression result unused}} if (int(a)+1) {} - for (int(a)+1;;) {} + for (int(a)+1;;) {} // expected-warning {{expression result unused}} a = sizeof(int()+1); a = sizeof(int(1)); typeof(int()+1) a2; // expected-error {{extension used}} (int(1)); // expected-warning {{expression result unused}} // type-id - (int())1; // expected-error {{used type 'int ()' where arithmetic or pointer type is required}} + (int())1; // expected-error {{C-style cast from 'int' to 'int ()' is not allowed}} // Declarations. int fd(T(a)); // expected-warning {{parentheses were disambiguated as a function declarator}} diff --git a/test/SemaCXX/decl-init-ref.cpp b/test/SemaCXX/decl-init-ref.cpp new file mode 100644 index 000000000000..d7db647cd11a --- /dev/null +++ b/test/SemaCXX/decl-init-ref.cpp @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only -verify -std=c++0x %s + +struct A {}; + +struct BASE { + operator A(); // expected-note {{candidate function}} +}; + +struct BASE1 { + operator A(); // expected-note {{candidate function}} +}; + +class B : public BASE , public BASE1 +{ + public: + B(); +} b; + +extern B f(); + +const int& ri = (void)0; // expected-error {{invalid initialization of reference of type 'int const &' from expression of type 'void'}} + +int main() { + const A& rca = f(); // expected-error {{rvalue reference cannot bind to lvalue due to multiple conversion functions}} + A& ra = f(); // expected-error {{non-const lvalue reference to type 'struct A' cannot be initialized with a temporary of type 'class B'}} +} diff --git a/test/SemaCXX/decltype-crash.cpp b/test/SemaCXX/decltype-crash.cpp new file mode 100644 index 000000000000..b56a7f602987 --- /dev/null +++ b/test/SemaCXX/decltype-crash.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +int& a(); + +void f() { + decltype(a()) c; // expected-error {{no matching function for call to 'decltype'}} +} diff --git a/test/SemaCXX/decltype-this.cpp b/test/SemaCXX/decltype-this.cpp new file mode 100644 index 000000000000..fc001063c510 --- /dev/null +++ b/test/SemaCXX/decltype-this.cpp @@ -0,0 +1,15 @@ +// RUN: clang-cc -fsyntax-only -verify -std=c++0x %t +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; +}; + +struct S { + void f() { static_assert(is_same<decltype(this), S*>::value, ""); } + void g() const { static_assert(is_same<decltype(this), const S*>::value, ""); } + void h() volatile { static_assert(is_same<decltype(this), volatile S*>::value, ""); } + void i() const volatile { static_assert(is_same<decltype(this), const volatile S*>::value, ""); } +}; diff --git a/test/SemaCXX/default-argument-temporaries.cpp b/test/SemaCXX/default-argument-temporaries.cpp new file mode 100644 index 000000000000..232351dcff3d --- /dev/null +++ b/test/SemaCXX/default-argument-temporaries.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct B { B(void* = 0); }; + +struct A { + A(B b = B()) { } +}; + +void f() { + (void)B(); + (void)A(); +} diff --git a/test/SemaCXX/default-assignment-operator.cpp b/test/SemaCXX/default-assignment-operator.cpp index 090ba3c3ca80..e627fefdef6d 100644 --- a/test/SemaCXX/default-assignment-operator.cpp +++ b/test/SemaCXX/default-assignment-operator.cpp @@ -26,7 +26,7 @@ Z z2; // Test1 void f(X x, const X cx) { - x = cx; // expected-note {{synthesized method is first required here}} + x = cx; // expected-note {{synthesized method is first required here}} x = cx; z1 = z2; } @@ -36,8 +36,7 @@ class T {}; T t1; T t2; -void g() -{ +void g() { t1 = t2; } @@ -51,8 +50,7 @@ public: class W : V {}; W w1, w2; -void h() -{ +void h() { w1 = w2; } @@ -67,8 +65,22 @@ public: class D1 : B1 {}; D1 d1, d2; -void i() -{ - d1 = d2; +void i() { + d1 = d2; +} + +// Test5 + +class E1 { // expected-error{{cannot define the implicit default assignment operator for 'class E1', because non-static const member 'a' can't use default assignment operator}} +public: + const int a; // expected-note{{declared at}} + E1() : a(0) {} + +}; + +E1 e1, e2; + +void j() { + e1 = e2; // expected-note{{synthesized method is first required here}} } diff --git a/test/SemaCXX/default-constructor-initializers.cpp b/test/SemaCXX/default-constructor-initializers.cpp index 24c53839622c..6cbb978dbb99 100644 --- a/test/SemaCXX/default-constructor-initializers.cpp +++ b/test/SemaCXX/default-constructor-initializers.cpp @@ -11,16 +11,16 @@ struct X2 : X1 { // expected-note {{'struct X2' declared here}} \ struct X3 : public X2 { }; -X3 x3; // expected-error {{cannot define the implicit default constructor for 'struct X3', because member 'struct X2' does not have any default constructor}} +X3 x3; // expected-error {{cannot define the implicit default constructor for 'struct X3', because base class 'struct X2' does not have any default constructor}} struct X4 { - X2 x2; + X2 x2; // expected-note {{member is declared here}} X2 & rx2; // expected-note {{declared at}} }; -X4 x4; // expected-error {{cannot define the implicit default constructor for 'struct X4', because base class 'struct X2' does not have any default constructor}} \ - // expected-error {{cannot define the implicit default constructor for 'struct X4', because reference member rx2 cannot be default-initialized}} +X4 x4; // expected-error {{cannot define the implicit default constructor for 'struct X4', because member's type 'struct X2' does not have any default constructor}} \ + // expected-error {{cannot define the implicit default constructor for 'struct X4', because reference member 'rx2' cannot be default-initialized}} struct Y1 { // has no implicit default constructor @@ -46,11 +46,11 @@ Y4 y4; struct Z1 { - int& z; // expected-note {{declared at}} - const int c1; // expected-note {{declared at}} - volatile int v1; + int& z; // expected-note {{declared at}} + const int c1; // expected-note {{declared at}} + volatile int v1; }; -Z1 z1; // expected-error {{cannot define the implicit default constructor for 'struct Z1', because reference member z cannot be default-initialized}} \ - // expected-error {{cannot define the implicit default constructor for 'struct Z1', because const member c1 cannot be default-initialized}} +Z1 z1; // expected-error {{cannot define the implicit default constructor for 'struct Z1', because reference member 'z' cannot be default-initialized}} \ + // expected-error {{cannot define the implicit default constructor for 'struct Z1', because const member 'c1' cannot be default-initialized}} diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp index edbd6b3e206a..183452070da4 100644 --- a/test/SemaCXX/default2.cpp +++ b/test/SemaCXX/default2.cpp @@ -24,20 +24,8 @@ int f1(int i, int i, int j) { // expected-error {{redefinition of parameter 'i'} int x; void g(int x, int y = x); // expected-error {{default argument references parameter 'x'}} -void h() -{ - int i; - extern void h2(int x = sizeof(i)); // expected-error {{default argument references local variable 'i' of enclosing function}} -} - void g2(int x, int y, int z = x + y); // expected-error {{default argument references parameter 'x'}} expected-error {{default argument references parameter 'y'}} -void nondecl(int (*f)(int x = 5)) // {expected-error {{default arguments can only be specified}}} -{ - void (*f2)(int = 17) // {expected-error {{default arguments can only be specified}}} - = (void (*)(int = 42))f; // {expected-error {{default arguments can only be specified}}} -} - class X { void f(X* x = this); // expected-error{{invalid use of 'this' outside of a nonstatic member function}} @@ -82,10 +70,6 @@ struct Y { }; static int b; - - int (*f)(int = 17); // expected-error{{default arguments can only be specified for parameters in a function declaration}} - - void mem8(int (*fp)(int) = (int (*)(int = 17))0); // expected-error{{default arguments can only be specified for parameters in a function declaration}} }; int Y::mem3(int i = b) { return i; } // OK; use X::b @@ -127,3 +111,9 @@ class C2 { static void g(int = f()); // expected-error{{use of default argument to function 'f' that is declared later in class 'C2'}} static int f(int = 10); // expected-note{{default argument declared here}} }; + +// Make sure we actually parse the default argument for an inline definition +class XX { + void A(int length = -1 ) { } + void B() { A(); } +}; diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp index 8064ed349b08..637b2b1b2d5c 100644 --- a/test/SemaCXX/deleted-function.cpp +++ b/test/SemaCXX/deleted-function.cpp @@ -18,7 +18,7 @@ void ov(double) = delete; // expected-note {{candidate function has been explici struct WithDel { WithDel() = delete; // expected-note {{candidate function has been explicitly deleted}} void fn() = delete; // expected-note {{function has been explicitly marked deleted here}} - operator int() = delete; + operator int() = delete; void operator +(int) = delete; int i = delete; // expected-error {{only functions can have deleted definitions}} diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp index f544db0b1b6e..790a401ae99c 100644 --- a/test/SemaCXX/destructor.cpp +++ b/test/SemaCXX/destructor.cpp @@ -40,8 +40,9 @@ struct F { ~F(); // expected-error {{destructor cannot be redeclared}} }; -~; // expected-error {{expected class name}} -~undef(); // expected-error {{expected class name}} +~; // expected-error {{expected the class name after '~' to name a destructor}} +~undef(); // expected-error {{expected the class name after '~' to name a destructor}} +~operator+(int, int); // expected-error {{expected the class name after '~' to name a destructor}} ~F(){} // expected-error {{destructor must be a non-static member function}} struct G { @@ -54,3 +55,9 @@ G::~G() { } struct H { ~H(void) { } }; + +struct X {}; + +struct Y { + ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}} +}; diff --git a/test/SemaCXX/direct-initializer.cpp b/test/SemaCXX/direct-initializer.cpp index 149b65c8d71d..a9e2b2bb6e45 100644 --- a/test/SemaCXX/direct-initializer.cpp +++ b/test/SemaCXX/direct-initializer.cpp @@ -34,3 +34,17 @@ void g() { Z z; // expected-error{{no matching constructor for initialization of 'z'}} } + +struct Base { + operator int*() const; +}; + +struct Derived : Base { + operator int*(); +}; + +void foo(const Derived cd, Derived d) { + int *pi = cd; // expected-error {{incompatible type initializing 'struct Derived const', expected 'int *'}} + int *ppi = d; + +} diff --git a/test/SemaCXX/empty-class-layout.cpp b/test/SemaCXX/empty-class-layout.cpp new file mode 100644 index 000000000000..8b54ea1c66f2 --- /dev/null +++ b/test/SemaCXX/empty-class-layout.cpp @@ -0,0 +1,68 @@ +// RUN: clang-cc -triple x86_64-unknown-unknown %s -fsyntax-only -verify + +#define SA(n, p) int a##n[(p) ? 1 : -1] + +struct A { int a; }; +SA(0, sizeof(A) == 4); + +struct B { }; +SA(1, sizeof(B) == 1); + +struct C : A, B { }; +SA(2, sizeof(C) == 4); + +struct D { }; +struct E : D { }; +struct F : E { }; + +struct G : E, F { }; +SA(3, sizeof(G) == 2); + +struct Empty { Empty(); }; + +struct I : Empty { + Empty e; +}; +SA(4, sizeof(I) == 2); + +struct J : Empty { + Empty e[2]; +}; +SA(5, sizeof(J) == 3); + +template<int N> struct Derived : Empty, Derived<N - 1> { +}; +template<> struct Derived<0> : Empty { }; + +struct S1 : virtual Derived<10> { + Empty e; +}; +SA(6, sizeof(S1) == 24); + +struct S2 : virtual Derived<10> { + Empty e[2]; +}; +SA(7, sizeof(S2) == 24); + +struct S3 { + Empty e; +}; + +struct S4 : Empty, S3 { +}; +SA(8, sizeof(S4) == 2); + +struct S5 : S3, Empty {}; +SA(9, sizeof(S5) == 2); + +struct S6 : S5 { }; +SA(10, sizeof(S6) == 2); + +struct S7 : Empty { + void *v; +}; +SA(11, sizeof(S7) == 8); + +struct S8 : Empty, A { +}; +SA(12, sizeof(S8) == 4); diff --git a/test/SemaCXX/enum.cpp b/test/SemaCXX/enum.cpp index 9668c84693d3..db256812ab80 100644 --- a/test/SemaCXX/enum.cpp +++ b/test/SemaCXX/enum.cpp @@ -14,14 +14,13 @@ void f() { // <rdar://problem/6502934> typedef enum Foo { - A = 0, - B = 1 + A = 0, + B = 1 } Foo; - - + void bar() { - Foo myvar = A; - myvar = B; + Foo myvar = A; + myvar = B; } /// PR3688 @@ -32,7 +31,7 @@ struct s1 { enum e1 { YES, NO }; static enum e1 badfunc(struct s1 *q) { - return q->bar(); // expected-error{{return type of called function ('enum s1::e1') is incomplete}} + return q->bar(); // expected-error{{calling function with incomplete return type 'enum s1::e1'}} } enum e2; // expected-error{{ISO C++ forbids forward references to 'enum' types}} diff --git a/test/SemaCXX/exception-spec.cpp b/test/SemaCXX/exception-spec.cpp index 5eba26e70c6f..9b2a07d79654 100644 --- a/test/SemaCXX/exception-spec.cpp +++ b/test/SemaCXX/exception-spec.cpp @@ -24,7 +24,7 @@ void (**j)() throw(int); // expected-error {{not allowed beyond a single}} // Pointer to function returning pointer to pointer to function with spec void (**(*h())())() throw(int); // expected-error {{not allowed beyond a single}} -struct Incomplete; +struct Incomplete; // expected-note 3 {{forward declaration}} // Exception spec must not have incomplete types, or pointers to them, except // void. @@ -61,3 +61,127 @@ void r7() throw(float); // expected-error {{exception specification in declarati // Top-level const doesn't matter. void r8() throw(int); void r8() throw(const int); + +// Multiple appearances don't matter. +void r9() throw(int, int); +void r9() throw(int, int); + +struct A +{ +}; + +struct B1 : A +{ +}; + +struct B2 : A +{ +}; + +struct D : B1, B2 +{ +}; + +struct P : private A +{ +}; + +struct Base +{ + virtual void f1() throw(); + virtual void f2(); + virtual void f3() throw(...); + virtual void f4() throw(int, float); + + virtual void f5() throw(int, float); + virtual void f6() throw(A); + virtual void f7() throw(A, int, float); + virtual void f8(); + + virtual void g1() throw(); // expected-note {{overridden virtual function is here}} + virtual void g2() throw(int); // expected-note {{overridden virtual function is here}} + virtual void g3() throw(A); // expected-note {{overridden virtual function is here}} + virtual void g4() throw(B1); // expected-note {{overridden virtual function is here}} + virtual void g5() throw(A); // expected-note {{overridden virtual function is here}} +}; +struct Derived : Base +{ + virtual void f1() throw(); + virtual void f2() throw(...); + virtual void f3(); + virtual void f4() throw(float, int); + + virtual void f5() throw(float); + virtual void f6() throw(B1); + virtual void f7() throw(B1, B2, int); + virtual void f8() throw(B2, B2, int, float, char, double, bool); + + virtual void g1() throw(int); // expected-error {{exception specification of overriding function is more lax}} + virtual void g2(); // expected-error {{exception specification of overriding function is more lax}} + virtual void g3() throw(D); // expected-error {{exception specification of overriding function is more lax}} + virtual void g4() throw(A); // expected-error {{exception specification of overriding function is more lax}} + virtual void g5() throw(P); // expected-error {{exception specification of overriding function is more lax}} +}; + +// Some functions to play with below. +void s1() throw(); +void s2() throw(int); +void s3() throw(A); +void s4() throw(B1); +void s5() throw(D); +void s6(); +void s7() throw(int, float); +void (*s8())() throw(B1); // s8 returns a pointer to function with spec +void s9(void (*)() throw(B1)); // s9 takes pointer to function with spec + +void fnptrs() +{ + // Assignment and initialization of function pointers. + void (*t1)() throw() = &s1; // valid + t1 = &s2; // expected-error {{not superset}} expected-error {{incompatible type}} + t1 = &s3; // expected-error {{not superset}} expected-error {{incompatible type}} + void (&t2)() throw() = s2; // expected-error {{not superset}} + void (*t3)() throw(int) = &s2; // valid + void (*t4)() throw(A) = &s1; // valid + t4 = &s3; // valid + t4 = &s4; // valid + t4 = &s5; // expected-error {{not superset}} expected-error {{incompatible type}} + void (*t5)() = &s1; // valid + t5 = &s2; // valid + t5 = &s6; // valid + t5 = &s7; // valid + t1 = t3; // expected-error {{not superset}} expected-error {{incompatible type}} + t3 = t1; // valid + void (*t6)() throw(B1); + t6 = t4; // expected-error {{not superset}} expected-error {{incompatible type}} + t4 = t6; // valid + t5 = t1; // valid + t1 = t5; // expected-error {{not superset}} expected-error {{incompatible type}} + + // return types and arguments must match exactly, no inheritance allowed + void (*(*t7)())() throw(B1) = &s8; // valid + void (*(*t8)())() throw(A) = &s8; // expected-error {{return types differ}} expected-error {{incompatible type}} + void (*(*t9)())() throw(D) = &s8; // expected-error {{return types differ}} expected-error {{incompatible type}} + void (*t10)(void (*)() throw(B1)) = &s9; // valid expected-warning{{disambiguated}} + void (*t11)(void (*)() throw(A)) = &s9; // expected-error {{argument types differ}} expected-error {{incompatible type}} expected-warning{{disambiguated}} + void (*t12)(void (*)() throw(D)) = &s9; // expected-error {{argument types differ}} expected-error {{incompatible type}} expected-warning{{disambiguated}} +} + +// Member function stuff + +struct Str1 { void f() throw(int); }; // expected-note {{previous declaration}} +void Str1::f() // expected-error {{does not match previous declaration}} +{ +} + +void mfnptr() +{ + void (Str1::*pfn1)() throw(int) = &Str1::f; // valid + void (Str1::*pfn2)() = &Str1::f; // valid + void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}} expected-error {{incompatible type}} +} + +// Don't suppress errors in template instantiation. +template <typename T> struct TEx; // expected-note {{template is declared here}} + +void tf() throw(TEx<int>); // expected-error {{implicit instantiation of undefined template}} diff --git a/test/SemaCXX/friend-class-nodecl.cpp b/test/SemaCXX/friend-class-nodecl.cpp new file mode 100644 index 000000000000..de12eaf741c5 --- /dev/null +++ b/test/SemaCXX/friend-class-nodecl.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -ast-print %s -o %t && +// RUN: not grep '^ *class B' %t + +// Tests that the tag decls in friend declarations aren't added to the +// declaring class's decl chain. + +class A { + friend class B; +}; + diff --git a/test/SemaCXX/function-overloaded-redecl.cpp b/test/SemaCXX/function-overloaded-redecl.cpp new file mode 100644 index 000000000000..4d8e57c1b9fe --- /dev/null +++ b/test/SemaCXX/function-overloaded-redecl.cpp @@ -0,0 +1,10 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +typedef const int cInt; + +void f (int); +void f (const int); // redecl + +void f (int) { } // expected-note {{previous definition is here}} +void f (cInt) { } // expected-error {{redefinition of 'f'}} + diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp index 0be7ddb53ae8..142dba7b13f7 100644 --- a/test/SemaCXX/functional-cast.cpp +++ b/test/SemaCXX/functional-cast.cpp @@ -1,4 +1,6 @@ -// RUN: clang-cc -fsyntax-only -verify %s +// RUN: clang-cc -fsyntax-only -verify -faccess-control %s + +// ------------ not interpreted as C-style cast ------------ struct SimpleValueInit { int i; @@ -25,3 +27,293 @@ void test_cxx_function_cast_multi() { (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}} } + + +// ------------------ everything else -------------------- + +struct A {}; + +// ----------- const_cast -------------- + +typedef char c; +typedef c *cp; +typedef cp *cpp; +typedef cpp *cppp; +typedef cppp &cpppr; +typedef const cppp &cpppcr; +typedef const char cc; +typedef cc *ccp; +typedef volatile ccp ccvp; +typedef ccvp *ccvpp; +typedef const volatile ccvpp ccvpcvp; +typedef ccvpcvp *ccvpcvpp; +typedef int iar[100]; +typedef iar &iarr; +typedef int (*f)(int); + +void t_cc() +{ + ccvpcvpp var = 0; + // Cast away deep consts and volatiles. + char ***var2 = cppp(var); + char ***const &var3 = var2; + // Const reference to reference. + char ***&var4 = cpppr(var3); + // Drop reference. Intentionally without qualifier change. + char *** var5 = cppp(var4); + const int ar[100] = {0}; + // Array decay. Intentionally without qualifier change. + typedef int *intp; + int *pi = intp(ar); + f fp = 0; + // Don't misidentify fn** as a function pointer. + typedef f *fp_t; + f *fpp = fp_t(&fp); + int const A::* const A::*icapcap = 0; + typedef int A::* A::*iapap_t; + iapap_t iapap = iapap_t(icapcap); +} + +// ----------- static_cast ------------- + +struct B : public A {}; // Single public base. +struct C1 : public virtual B {}; // Single virtual base. +struct C2 : public virtual B {}; +struct D : public C1, public C2 {}; // Diamond +struct E : private A {}; // Single private base. +struct F : public C1 {}; // Single path to B with virtual. +struct G1 : public B {}; +struct G2 : public B {}; +struct H : public G1, public G2 {}; // Ambiguous path to B. + +enum Enum { En1, En2 }; +enum Onom { On1, On2 }; + +struct Co1 { operator int(); }; +struct Co2 { Co2(int); }; +struct Co3 { }; +struct Co4 { Co4(Co3); operator Co3(); }; + +// Explicit implicits +void t_529_2() +{ + int i = 1; + (void)float(i); + double d = 1.0; + (void)float(d); + (void)int(d); + (void)char(i); + typedef unsigned long ulong; + (void)ulong(i); + (void)int(En1); + (void)double(En1); + typedef int &intr; + (void)intr(i); + typedef const int &cintr; + (void)cintr(i); + + int ar[1]; + typedef const int *cintp; + (void)cintp(ar); + typedef void (*pfvv)(); + (void)pfvv(t_529_2); + + typedef void *voidp; + (void)voidp(0); + (void)voidp((int*)0); + typedef volatile const void *vcvoidp; + (void)vcvoidp((const int*)0); + typedef A *Ap; + (void)Ap((B*)0); + typedef A &Ar; + (void)Ar(*((B*)0)); + typedef const B *cBp; + (void)cBp((C1*)0); + typedef B &Br; + (void)Br(*((C1*)0)); + (void)Ap((D*)0); + typedef const A &cAr; + (void)cAr(*((D*)0)); + typedef int B::*Bmp; + (void)Bmp((int A::*)0); + typedef void (B::*Bmfp)(); + (void)Bmfp((void (A::*)())0); + (void)Ap((E*)0); // functional-style cast ignores access control + (void)voidp((const int*)0); // const_cast appended + + (void)int(Co1()); + (void)Co2(1); + (void)Co3((Co4)(Co3())); + + // Bad code below + //(void)(A*)((H*)0); // {{static_cast from 'struct H *' to 'struct A *' is not allowed}} +} + +// Anything to void +void t_529_4() +{ + void(1); + (void(t_529_4)); +} + +// Static downcasts +void t_529_5_8() +{ + typedef B *Bp; + (void)Bp((A*)0); + typedef B &Br; + (void)Br(*((A*)0)); + typedef const G1 *cG1p; + (void)cG1p((A*)0); + typedef const G1 &cG1r; + (void)cG1r(*((A*)0)); + (void)Bp((const A*)0); // const_cast appended + (void)Br(*((const A*)0)); // const_cast appended + typedef E *Ep; + (void)Ep((A*)0); // access control ignored + typedef E &Er; + (void)Er(*((A*)0)); // access control ignored + + // Bad code below + + typedef C1 *C1p; + (void)C1p((A*)0); // expected-error {{cannot cast 'struct A *' to 'C1p' (aka 'struct C1 *') via virtual base 'struct B'}} + typedef C1 &C1r; + (void)C1r(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'C1r' (aka 'struct C1 &') via virtual base 'struct B'}} + typedef D *Dp; + (void)Dp((A*)0); // expected-error {{cannot cast 'struct A *' to 'Dp' (aka 'struct D *') via virtual base 'struct B'}} + typedef D &Dr; + (void)Dr(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'Dr' (aka 'struct D &') via virtual base 'struct B'}} + typedef H *Hp; + (void)Hp((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + typedef H &Hr; + (void)Hr(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + + // TODO: Test DR427. This requires user-defined conversions, though. +} + +// Enum conversions +void t_529_7() +{ + (void)Enum(1); + (void)Enum(1.0); + (void)Onom(En1); + + // Bad code below + + (void)Enum((int*)0); // expected-error {{functional-style cast from 'int *' to 'enum Enum' is not allowed}} +} + +// Void pointer to object pointer +void t_529_10() +{ + typedef int *intp; + (void)intp((void*)0); + typedef const A *cAp; + (void)cAp((void*)0); + (void)intp((const void*)0); // const_cast appended +} + +// Member pointer upcast. +void t_529_9() +{ + typedef int A::*Amp; + (void)Amp((int B::*)0); + + // Bad code below + (void)Amp((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}} + (void)Amp((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}} +} + +// -------- reinterpret_cast ----------- + +enum test { testval = 1 }; +struct structure { int m; }; +typedef void (*fnptr)(); + +// Test conversion between pointer and integral types, as in p3 and p4. +void integral_conversion() +{ + typedef void *voidp; + void *vp = voidp(testval); + long l = long(vp); + typedef float *floatp; + (void)floatp(l); + fnptr fnp = fnptr(l); + (void)char(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}} + (void)long(fnp); +} + +void pointer_conversion() +{ + int *p1 = 0; + typedef float *floatp; + float *p2 = floatp(p1); + typedef structure *structurep; + structure *p3 = structurep(p2); + typedef int **ppint; + typedef ppint *pppint; + ppint *deep = pppint(p3); + typedef fnptr fnptrp; + (void)fnptrp(deep); +} + +void constness() +{ + int ***const ipppc = 0; + typedef int const *icp_t; + int const *icp = icp_t(ipppc); + typedef int *intp; + (void)intp(icp); // const_cast appended + typedef int const *const ** intcpcpp; + intcpcpp icpcpp = intcpcpp(ipppc); // const_cast appended + int *ip = intp(icpcpp); + (void)icp_t(ip); + typedef int const *const *const *intcpcpcp; + (void)intcpcpcp(ipppc); +} + +void fnptrs() +{ + typedef int (*fnptr2)(int); + fnptr fp = 0; + (void)fnptr2(fp); + typedef void *voidp; + void *vp = voidp(fp); + (void)fnptr(vp); +} + +void refs() +{ + long l = 0; + typedef char &charr; + char &c = charr(l); + // Bad: from rvalue + typedef int &intr; + (void)intr(&c); // expected-error {{functional-style cast from rvalue to reference type 'intr' (aka 'int &')}} +} + +void memptrs() +{ + const int structure::*psi = 0; + typedef const float structure::*structurecfmp; + (void)structurecfmp(psi); + typedef int structure::*structureimp; + (void)structureimp(psi); // const_cast appended + + void (structure::*psf)() = 0; + typedef int (structure::*structureimfp)(); + (void)structureimfp(psf); + + typedef void (structure::*structurevmfp)(); + (void)structurevmfp(psi); // expected-error {{functional-style cast from 'int const struct structure::*' to 'structurevmfp' (aka 'void (struct structure::*)()') is not allowed}} + (void)structureimp(psf); // expected-error {{functional-style cast from 'void (struct structure::*)()' to 'structureimp' (aka 'int struct structure::*') is not allowed}} +} + +// ---------------- misc ------------------ + +void crash_on_invalid_1() +{ + typedef itn Typo; // expected-error {{unknown type name 'itn'}} + (void)Typo(1); // used to crash +} diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp index 32d04e2da40b..785ea0efa401 100644 --- a/test/SemaCXX/i-c-e-cxx.cpp +++ b/test/SemaCXX/i-c-e-cxx.cpp @@ -4,3 +4,13 @@ const int c = 10; int ar[c]; + +struct X0 { + static const int value = static_cast<int>(4.0); +}; + +void f() { + if (const int value = 17) { + int array[value]; + } +} diff --git a/test/SemaCXX/illegal-member-initialization.cpp b/test/SemaCXX/illegal-member-initialization.cpp new file mode 100644 index 000000000000..2d7c73d68a3f --- /dev/null +++ b/test/SemaCXX/illegal-member-initialization.cpp @@ -0,0 +1,22 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct A { + A() : value(), cvalue() { } // expected-error {{cannot initialize the member to null in default constructor because reference member 'value' cannot be null-initialized}} \ + // expected-error {{constructor for 'struct A' must explicitly initialize the reference member 'value'}} + int &value; // expected-note{{declared at}} {{expected-note{{declared at}} + const int cvalue; +}; + +struct B { +}; + +struct X { + X() { } // expected-error {{constructor for 'struct X' must explicitly initialize the reference member 'value'}} \ + // expected-error {{constructor for 'struct X' must explicitly initialize the const member 'cvalue'}} \ + // expected-error {{constructor for 'struct X' must explicitly initialize the reference member 'b'}} \ + // expected-error {{constructor for 'struct X' must explicitly initialize the const member 'cb'}} + int &value; // expected-note{{declared at}} + const int cvalue; // expected-note{{declared at}} + B& b; // expected-note{{declared at}} + const B cb; // expected-note{{declared at}} +}; diff --git a/test/SemaCXX/incomplete-call.cpp b/test/SemaCXX/incomplete-call.cpp new file mode 100644 index 000000000000..6134189f0a9a --- /dev/null +++ b/test/SemaCXX/incomplete-call.cpp @@ -0,0 +1,38 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct A; // expected-note 13 {{forward declaration of 'struct A'}} + +A f(); // expected-note {{note: 'f' declared here}} + +struct B { + A f(); // expected-note {{'f' declared here}} + A operator()(); // expected-note 2 {{'operator()' declared here}} + operator A(); // expected-note {{'operator A' declared here}} + A operator!(); // expected-note 2 {{'operator!' declared here}} + A operator++(int); // expected-note {{'operator++' declared here}} + A operator[](int); // expected-note {{'operator[]' declared here}} + A operator+(int); // expected-note {{'operator+' declared here}} + A operator->(); // expected-note {{'operator->' declared here}} +}; + +void g() { + f(); // expected-error {{calling 'f' with incomplete return type 'struct A'}} + + typedef A (*Func)(); + Func fp; + fp(); // expected-error {{calling function with incomplete return type 'struct A'}} + ((Func)0)(); // expected-error {{calling function with incomplete return type 'struct A'}} + + B b; + b.f(); // expected-error {{calling 'f' with incomplete return type 'struct A'}} + + b.operator()(); // expected-error {{calling 'operator()' with incomplete return type 'struct A'}} + b.operator A(); // expected-error {{calling 'operator A' with incomplete return type 'struct A'}} + b.operator!(); // expected-error {{calling 'operator!' with incomplete return type 'struct A'}} + + !b; // expected-error {{calling 'operator!' with incomplete return type 'struct A'}} + b(); // expected-error {{calling 'operator()' with incomplete return type 'struct A'}} + b++; // expected-error {{calling 'operator++' with incomplete return type 'struct A'}} + b[0]; // expected-error {{calling 'operator[]' with incomplete return type 'struct A'}} + b + 1; // expected-error {{calling 'operator+' with incomplete return type 'struct A'}} + b->f(); // expected-error {{calling 'operator->' with incomplete return type 'struct A'}} +} diff --git a/test/SemaCXX/inherit.cpp b/test/SemaCXX/inherit.cpp index eaad97cc82a0..069e30d0cdfa 100644 --- a/test/SemaCXX/inherit.cpp +++ b/test/SemaCXX/inherit.cpp @@ -10,7 +10,7 @@ class B3 : virtual virtual A { }; // expected-error{{duplicate 'virtual' in base class C : public B1, private B2 { }; -class D; // expected-note {{forward declaration of 'class D'}} +class D; // expected-note {{forward declaration of 'class D'}} class E : public D { }; // expected-error{{base class has incomplete type}} diff --git a/test/SemaCXX/invalid-member-expr.cpp b/test/SemaCXX/invalid-member-expr.cpp new file mode 100644 index 000000000000..90932ed65e31 --- /dev/null +++ b/test/SemaCXX/invalid-member-expr.cpp @@ -0,0 +1,21 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class X {}; + +void test() { + X x; + + x.int; // expected-error{{expected identifier}} + x.~int(); // expected-error{{expected identifier}} + x.operator; // expected-error{{missing type specifier after 'operator'}} + x.operator typedef; // expected-error{{missing type specifier after 'operator'}} +} + +void test2() { + X *x; + + x->int; // expected-error{{expected identifier}} + x->~int(); // expected-error{{expected identifier}} + x->operator; // expected-error{{missing type specifier after 'operator'}} + x->operator typedef; // expected-error{{missing type specifier after 'operator'}} +} diff --git a/test/SemaCXX/invalid-template-specifier.cpp b/test/SemaCXX/invalid-template-specifier.cpp new file mode 100644 index 000000000000..a3f081ff60b5 --- /dev/null +++ b/test/SemaCXX/invalid-template-specifier.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc %s -verify -fsyntax-only +// PR4809 +// This test is primarily checking that this doesn't crash, not the particular +// diagnostics. + +const template basic_istream<char>; // expected-error {{expected unqualified-id}} + +namespace S {} +template <class X> class Y { + void x() { S::template y<char>(1); } // expected-error {{does not refer to a template}} \ + // expected-error {{no member named 'y'}} +}; diff --git a/test/SemaCXX/libstdcxx_is_pod_hack.cpp b/test/SemaCXX/libstdcxx_is_pod_hack.cpp new file mode 100644 index 000000000000..df064bc6a0fa --- /dev/null +++ b/test/SemaCXX/libstdcxx_is_pod_hack.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only %s + +template<typename T> +struct __is_pod { +}; + +__is_pod<int> ipi; diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp index 864953e9f9c2..b4c72f557d2a 100644 --- a/test/SemaCXX/linkage-spec.cpp +++ b/test/SemaCXX/linkage-spec.cpp @@ -25,3 +25,11 @@ extern "C" int const bar; // <rdar://problem/6895431> extern "C" struct bar d; extern struct bar e; + +extern "C++" { + namespace N0 { + struct X0 { + int foo(int x) { return x; } + }; + } +}
\ No newline at end of file diff --git a/test/SemaCXX/member-expr-static.cpp b/test/SemaCXX/member-expr-static.cpp index b6495a852041..2fa7e0781c1e 100644 --- a/test/SemaCXX/member-expr-static.cpp +++ b/test/SemaCXX/member-expr-static.cpp @@ -2,20 +2,18 @@ typedef void (*thread_continue_t)(); extern "C" { -extern void kernel_thread_start(thread_continue_t continuation); -extern void pure_c(void); + extern void kernel_thread_start(thread_continue_t continuation); + extern void pure_c(void); } -class _IOConfigThread -{ +class _IOConfigThread { public: - static void main( void ); + static void main( void ); }; -void foo( void ) -{ - kernel_thread_start(&_IOConfigThread::main); - kernel_thread_start((thread_continue_t)&_IOConfigThread::main); - kernel_thread_start(&pure_c); +void foo( void ) { + kernel_thread_start(&_IOConfigThread::main); + kernel_thread_start((thread_continue_t)&_IOConfigThread::main); + kernel_thread_start(&pure_c); } diff --git a/test/SemaCXX/member-name-lookup.cpp b/test/SemaCXX/member-name-lookup.cpp index 9fcd922ddf7d..e95641b4bf9c 100644 --- a/test/SemaCXX/member-name-lookup.cpp +++ b/test/SemaCXX/member-name-lookup.cpp @@ -146,3 +146,13 @@ struct HasAnotherMemberType : HasMemberType1, HasMemberType2 { struct UsesAmbigMemberType : HasMemberType1, HasMemberType2 { type t; // expected-error{{member 'type' found in multiple base classes of different types}} }; + +struct X0 { + struct Inner { + static const int m; + }; + + static const int n = 17; +}; + +const int X0::Inner::m = n; diff --git a/test/SemaCXX/member-operator-expr.cpp b/test/SemaCXX/member-operator-expr.cpp new file mode 100644 index 000000000000..4d0e00fd6010 --- /dev/null +++ b/test/SemaCXX/member-operator-expr.cpp @@ -0,0 +1,29 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class X { +public: + int operator++(); + operator int(); +}; + +void test() { + X x; + int i; + + i = x.operator++(); + 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'}} +} + +void test2() { + X *x; + int i; + + i = x->operator++(); + 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'}} +} diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp index 3b106d5576fe..d13b16e6d672 100644 --- a/test/SemaCXX/member-pointer.cpp +++ b/test/SemaCXX/member-pointer.cpp @@ -40,6 +40,14 @@ void f() { // Conversion to member of base. pdi1 = pdid; // expected-error {{incompatible type assigning 'int struct D::*', expected 'int struct A::*'}} + + // Comparisons + int (A::*pf2)(int, int); + int (D::*pf3)(int, int) = 0; + bool b1 = (pf == pf2); (void)b1; + bool b2 = (pf != pf2); (void)b2; + bool b3 = (pf == pf3); (void)b3; + bool b4 = (pf != 0); (void)b4; } struct TheBase @@ -91,7 +99,7 @@ void h() { int i = phm->*pi; (void)&(hm.*pi); (void)&(phm->*pi); - (void)&((&hm)->*pi); // expected-error {{address expression must be an lvalue or a function designator}} + (void)&((&hm)->*pi); void (HasMembers::*pf)() = &HasMembers::f; (hm.*pf)(); diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp new file mode 100644 index 000000000000..28ad9a04e790 --- /dev/null +++ b/test/SemaCXX/missing-members.cpp @@ -0,0 +1,36 @@ +// RUN: clang-cc -fsyntax-only -verify %s +namespace A { + namespace B { + class C { }; + struct S { }; + union U { }; + } +} + +void f() { + A::B::i; // expected-error {{no member named 'i' in namespace 'A::B'}} + A::B::C::i; // expected-error {{no member named 'i' in 'class A::B::C'}} + ::i; // expected-error {{no member named 'i' in the global namespace}} +} + +namespace B { + class B { }; +} + +void g() { + A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}} + B::B::C::D; // expected-error {{no member named 'C' in 'class B::B'}} + ::C::D; // expected-error {{no member named 'C' in the global namespace}} +} + +int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}} +int A::B::C::i = 10; // expected-error {{no member named 'i' in 'class A::B::C'}} +int A::B::S::i = 10; // expected-error {{no member named 'i' in 'struct A::B::S'}} +int A::B::U::i = 10; // expected-error {{no member named 'i' in 'union A::B::U'}} + +using A::B::D; // expected-error {{no member named 'D' in namespace 'A::B'}} + +struct S : A::B::C { + using A::B::C::f; // expected-error {{no member named 'f' in 'class A::B::C'}} + +}; diff --git a/test/SemaCXX/namespace.cpp b/test/SemaCXX/namespace.cpp index 696ea818f657..5ed6ba50ce1b 100644 --- a/test/SemaCXX/namespace.cpp +++ b/test/SemaCXX/namespace.cpp @@ -8,7 +8,8 @@ void f() { A = 0; } // expected-error {{unexpected namespace name 'A': expected int A; // expected-error {{redefinition of 'A' as different kind of symbol}} class A; // expected-error {{redefinition of 'A' as different kind of symbol}} -class B {}; // expected-note {{previous definition is here}} +class B {}; // expected-note {{previous definition is here}} \ + // FIXME: ugly expected-note{{candidate function}} void C(); // expected-note {{previous definition is here}} namespace C {} // expected-error {{redefinition of 'C' as different kind of symbol}} @@ -66,4 +67,4 @@ namespace foo { static foo::x test1; // ok -static foo::X test2; // typo: expected-error {{unknown type name 'X'}} +static foo::X test2; // typo: expected-error {{no type named 'X' in}} diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp index 8fff8a2b2cbc..5178557030b7 100644 --- a/test/SemaCXX/nested-name-spec.cpp +++ b/test/SemaCXX/nested-name-spec.cpp @@ -13,8 +13,8 @@ namespace A { } A:: ; // expected-error {{expected unqualified-id}} -::A::ax::undef ex3; // expected-error {{expected a class or namespace}} expected-error {{unknown type name 'undef'}} -A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}} expected-error {{unknown type name 'undef2'}} +::A::ax::undef ex3; // expected-error {{no member named}} +A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}} int A::C::Ag1() { return 0; } @@ -35,9 +35,9 @@ class C2 { int x; }; -void C2::m() const { } // expected-error{{out-of-line definition does not match any declaration in 'C2'}} +void C2::m() const { } // expected-error{{out-of-line definition of 'm' does not match any declaration in 'class C2'}} -void C2::f(int) { } // expected-error{{out-of-line definition does not match any declaration in 'C2'}} +void C2::f(int) { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'class C2'}} void C2::m() { x = 0; @@ -125,7 +125,7 @@ class Operators { operator bool(); }; -Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition does not match any declaration in 'Operators'}} +Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition of 'operator+' does not match any declaration in 'class Operators'}} Operators ops; return ops; } @@ -143,13 +143,13 @@ namespace A { void g(int&); // expected-note{{member declaration nearly matches}} } -void A::f() {} // expected-error{{out-of-line definition does not match any declaration in 'A'}} +void A::f() {} // expected-error{{out-of-line definition of 'f' does not match any declaration in namespace 'A'}} -void A::g(const int&) { } // expected-error{{out-of-line definition does not match any declaration in 'A'}} +void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does not match any declaration in namespace 'A'}} struct Struct { }; -void Struct::f() { } // expected-error{{out-of-line definition does not match any declaration in 'Struct'}} +void Struct::f() { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'struct Struct'}} void global_func(int); void global_func2(int); @@ -166,13 +166,16 @@ void N::f() { } // okay struct Y; // expected-note{{forward declaration of 'struct Y'}} Y::foo y; // expected-error{{incomplete type 'struct Y' named in nested name specifier}} \ - // expected-error{{unknown type name 'foo'}} + // expected-error{{no type named 'foo' in}} X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}} \ // expected-error{{C++ requires a type specifier for all declarations}} \ // expected-error{{only constructors take base initializers}} - +struct foo_S { + static bool value; +}; +bool (foo_S::value); namespace somens { diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp index f890bf56e36b..c67a3f653900 100644 --- a/test/SemaCXX/new-delete.cpp +++ b/test/SemaCXX/new-delete.cpp @@ -38,10 +38,11 @@ void good_news() ia4 *pai = new (int[3][4]); pi = ::new int; U *pu = new (ps) U; - // FIXME: Inherited functions are not looked up currently. - //V *pv = new (ps) V; + V *pv = new (ps) V; pi = new (S(1.0f, 2)) int; + + (void)new int[true]; } struct abstract { @@ -95,3 +96,43 @@ void bad_deletes() delete (T*)0; // expected-warning {{deleting pointer to incomplete type}} ::S::delete (int*)0; // expected-error {{expected unqualified-id}} } + +struct X0 { }; + +struct X1 { + operator int*(); + operator float(); +}; + +struct X2 { + operator int*(); // expected-note {{candidate function}} + operator float*(); // expected-note {{candidate function}} +}; + +void test_delete_conv(X0 x0, X1 x1, X2 x2) { + delete x0; // expected-error{{cannot delete}} + delete x1; + delete x2; // expected-error{{ambiguous conversion of delete expression of type 'struct X2' to a pointer}} +} + +// PR4782 +class X3 { +public: + static void operator delete(void * mem, unsigned long size); +}; + +class X4 { +public: + static void release(X3 *x); + static void operator delete(void * mem, unsigned long size); +}; + + +void X4::release(X3 *x) { + delete x; +} + +class X5 { +public: + void Destroy() const { delete this; } +}; diff --git a/test/SemaCXX/overload-value-dep-arg.cpp b/test/SemaCXX/overload-value-dep-arg.cpp new file mode 100644 index 000000000000..1e94d5a30136 --- /dev/null +++ b/test/SemaCXX/overload-value-dep-arg.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class C { + C(void*); +}; + +int f(const C&); +int f(unsigned long); + +template<typename T> int f(const T* t) { + return f(reinterpret_cast<unsigned long>(t)); +} + diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp index 2a6c24a6778a..0284b2929b3c 100644 --- a/test/SemaCXX/overloaded-builtin-operators.cpp +++ b/test/SemaCXX/overloaded-builtin-operators.cpp @@ -20,11 +20,21 @@ struct Enum2 { operator E2(); }; + +struct X { + void f(); +}; + +typedef void (X::*pmf)(); +struct Xpmf { + operator pmf(); +}; + yes& islong(long); yes& islong(unsigned long); // FIXME: shouldn't be needed no& islong(int); -void f(Short s, Long l, Enum1 e1, Enum2 e2) { +void f(Short s, Long l, Enum1 e1, Enum2 e2, Xpmf pmf) { // C++ [over.built]p8 int i1 = +e1; int i2 = -e2; @@ -37,6 +47,10 @@ void f(Short s, Long l, Enum1 e1, Enum2 e2) { (void)static_cast<yes&>(islong(s + l)); (void)static_cast<no&>(islong(s + s)); + // C++ [over.built]p16 + (void)(pmf == &X::f); + (void)(pmf == 0); + // C++ [over.built]p17 (void)static_cast<yes&>(islong(s % l)); (void)static_cast<yes&>(islong(l << s)); @@ -45,7 +59,7 @@ void f(Short s, Long l, Enum1 e1, Enum2 e2) { // FIXME: should pass (void)static_cast<no&>(islong(e1 % e2)); } -struct ShortRef { +struct ShortRef { // expected-note{{candidate function}} operator short&(); }; @@ -53,7 +67,15 @@ struct LongRef { operator volatile long&(); }; -void g(ShortRef sr, LongRef lr) { +struct XpmfRef { // expected-note{{candidate function}} + operator pmf&(); +}; + +struct E2Ref { + operator E2&(); +}; + +void g(ShortRef sr, LongRef lr, E2Ref e2_ref, XpmfRef pmf_ref) { // C++ [over.built]p3 short s1 = sr++; @@ -64,6 +86,14 @@ void g(ShortRef sr, LongRef lr) { short& sr1 = (sr *= lr); volatile long& lr1 = (lr *= sr); + // C++ [over.built]p20: + E2 e2r2; + e2r2 = e2_ref; + + pmf &pmr = (pmf_ref = &X::f); // expected-error{{no viable overloaded '='}} + pmf pmr2; + pmr2 = pmf_ref; + // C++ [over.built]p22 short& sr2 = (sr %= lr); volatile long& lr2 = (lr <<= sr); diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index 916d753a3ff5..8f71ad538138 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -28,12 +28,12 @@ void g(Y y, Z z) { } struct A { - bool operator==(Z&); // expected-note{{candidate function}} + bool operator==(Z&); // expected-note 2{{candidate function}} }; A make_A(); -bool operator==(A&, Z&); // expected-note{{candidate function}} +bool operator==(A&, Z&); // expected-note 2{{candidate function}} void h(A a, const A ac, Z z) { make_A() == z; @@ -155,7 +155,7 @@ typedef INTREF Func1(FLOAT, double); typedef float& Func2(int, double); struct ConvertToFunc { - operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} + operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(float, double)'}} operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} void operator()(); }; @@ -209,3 +209,34 @@ namespace M { (void)(x + x); } } + +struct AA { bool operator!=(AA&); }; +struct BB : AA {}; +bool x(BB y, BB z) { return y != z; } + + +struct AX { + AX& operator ->(); // expected-note {{declared at}} + int b; +}; + +void m() { + AX a; + a->b = 0; // expected-error {{circular pointer delegation detected}} +} + +struct CircA { + struct CircB& operator->(); // expected-note {{declared at}} + int val; +}; +struct CircB { + struct CircC& operator->(); // expected-note {{declared at}} +}; +struct CircC { + struct CircA& operator->(); // expected-note {{declared at}} +}; + +void circ() { + CircA a; + a->val = 0; // expected-error {{circular pointer delegation detected}} +} diff --git a/test/SemaCXX/primary-base.cpp b/test/SemaCXX/primary-base.cpp new file mode 100644 index 000000000000..62f9087bd91d --- /dev/null +++ b/test/SemaCXX/primary-base.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc -fsyntax-only -verify %s +class A { virtual void f(); }; +class B : virtual A { }; + +class C : B { }; + +// Since A is already a primary base class, C should be the primary base class of F. +class F : virtual A, virtual C { }; + +int sa[sizeof(F) == sizeof(A) ? 1 : -1]; + diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp new file mode 100644 index 000000000000..1f05e81df530 --- /dev/null +++ b/test/SemaCXX/pseudo-destructors.cpp @@ -0,0 +1,40 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct A {}; + +enum Foo { F }; +typedef Foo Bar; + +typedef int Integer; + +void g(); + +namespace N { + typedef Foo Wibble; +} + +void f(A* a, Foo *f, int *i) { + a->~A(); + a->A::~A(); + + a->~foo(); // expected-error{{identifier 'foo' in pseudo-destructor expression does not name a type}} + + // FIXME: the type printed below isn't wonderful + a->~Bar(); // expected-error{{no member named}} + + f->~Bar(); + f->~Foo(); + i->~Bar(); // expected-error{{does not match}} + + g().~Bar(); // expected-error{{non-scalar}} + + f->::~Bar(); + f->N::~Wibble(); + + f->::~Bar(17, 42); // expected-error{{cannot have any arguments}} +} + +typedef int Integer; + +void destroy_without_call(int *ip) { + ip->~Integer; // expected-error{{called immediately}} +}
\ No newline at end of file diff --git a/test/SemaCXX/qual-id-test.cpp b/test/SemaCXX/qual-id-test.cpp new file mode 100644 index 000000000000..ecb6aa9b3592 --- /dev/null +++ b/test/SemaCXX/qual-id-test.cpp @@ -0,0 +1,140 @@ +// RUN: clang-cc -fsyntax-only -verify %s +namespace A +{ + namespace B + { + struct base // expected-note{{object type}} + { + void x() {} + void y() {} + }; + } + + struct member + { + void foo(); + }; + + struct middleman + { + member * operator->() { return 0; } + }; + + struct sub : B::base + { + void x() {} + middleman operator->() { return middleman(); } + }; +} + +struct bad +{ + int x(); +}; + +namespace C +{ + void fun() + { + A::sub a; + + a.x(); + + a.sub::x(); + a.base::x(); + + a.B::base::x(); // expected-error{{use of undeclared identifier 'B'}} + + a.A::sub::x(); + a.A::B::base::x(); + + a.bad::x(); // expected-error{{type 'struct bad' is not a direct or virtual base of ''struct A::sub''}} + + a->foo(); + a->member::foo(); + a->A::member::foo(); + } + + void fun2() + { + A::sub *a; + + a->x(); + + a->sub::x(); + a->base::x(); + + a->B::base::x(); // expected-error{{use of undeclared identifier 'B'}} + + a->A::sub::x(); + a->A::B::base::x(); + + a->bad::x(); // expected-error{{type 'struct bad' is not a direct or virtual base of ''struct A::sub''}} + + (*a)->foo(); + (*a)->member::foo(); + (*a)->A::member::foo(); + } + + void fun3() + { + int i; + i.foo(); // expected-error{{member reference base type 'int' is not a structure or union}} + } + + void fun4a() { + A::sub *a; + + typedef A::member base; // expected-note{{current scope}} + a->base::x(); // expected-error{{ambiguous}} + } + + void fun4b() { + A::sub *a; + + typedef A::B::base base; + a->base::x(); + } + + template<typename T> + void fun5() + { + T a; + a.x(); + a->foo(); + + a.A::sub::x(); + a.A::B::base::x(); + a->A::member::foo(); + + a.bad::x(); // expected-error{{direct or virtual}} + } + + void test_fun5() { + fun5<A::sub>(); // expected-note{{instantiation}} + } + + template<typename T> + void fun6() { + T a; + a.sub::x(); + a.base::x(); + a->member::foo(); + a.B::base::x(); // expected-error{{use of undeclared identifier 'B'}} + } + + void test_fun6() { + fun6<A::sub>(); // expected-note{{instantiation}} + } + +} + +// PR4703 +struct a { + int a; + static int sa; +}; + +a a; + +int a::sa = a.a; diff --git a/test/SemaCXX/ref-init-ambiguous.cpp b/test/SemaCXX/ref-init-ambiguous.cpp new file mode 100644 index 000000000000..dda1ead7b622 --- /dev/null +++ b/test/SemaCXX/ref-init-ambiguous.cpp @@ -0,0 +1,28 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +enum E2 { }; + +struct A { + operator E2&(); // expected-note 3 {{candidate function}} +}; + +struct B { + operator E2&(); // expected-note 3 {{candidate function}} +}; + +struct C : B, A { +}; + +void test(C c) { + const E2 &e2 = c; // expected-error {{reference initialization of type 'enum E2 const &' with initializer of type 'struct C' is ambiguous}} +} + +void foo(const E2 &); + +const E2 & re(C c) { + foo(c); // expected-error {{reference initialization of type 'enum E2 const &' with initializer of type 'struct C' is ambiguous}} + + return c; // expected-error {{reference initialization of type 'enum E2 const &' with initializer of type 'struct C' is ambiguous}} +} + + diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp index 9067a8661d7c..e03abf4300a3 100644 --- a/test/SemaCXX/references.cpp +++ b/test/SemaCXX/references.cpp @@ -87,3 +87,18 @@ void test8(int& const,// expected-error{{'const' qualifier may not be applied to typedef intref const intref_c; // okay. FIXME: how do we verify that this is the same type as intref? } + + +class string { + char *Data; + unsigned Length; +public: + string(); + ~string(); +}; + +string getInput(); + +void test9() { + string &s = getInput(); // expected-error{{lvalue reference}} +} diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp new file mode 100644 index 000000000000..03b0ddb87965 --- /dev/null +++ b/test/SemaCXX/return.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +int test1() { + throw; +} + +// PR5071 +template<typename T> T f() { } + +template<typename T> +void g(T t) { + return t * 2; // okay +} + +template<typename T> +T h() { + return 17; +} diff --git a/test/SemaCXX/static-array-member.cpp b/test/SemaCXX/static-array-member.cpp new file mode 100644 index 000000000000..dac70cd2eabf --- /dev/null +++ b/test/SemaCXX/static-array-member.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only %s + +struct X0 { + static int array[]; + + int x; + int y; +}; + +int X0::array[sizeof(X0) * 2]; + +template<typename T, int N> +struct X1 { + static T array[]; +}; + +template<typename T, int N> +T X1<T, N>::array[N]; diff --git a/test/SemaCXX/static-cast-complete-type.cpp b/test/SemaCXX/static-cast-complete-type.cpp new file mode 100644 index 000000000000..83583a5adf8e --- /dev/null +++ b/test/SemaCXX/static-cast-complete-type.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s +template<typename T> struct S { + S(int); +}; + +struct T; // expected-note{{forward declaration of 'struct T'}} + +void f() { + S<int> s0 = static_cast<S<int> >(0); + S<void*> s1 = static_cast<S<void*> >(00); + + (void)static_cast<T>(10); // expected-error{{'struct T' is an incomplete type}} +} diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp index b5c515d5e161..8db8e33b93ce 100644 --- a/test/SemaCXX/static-cast.cpp +++ b/test/SemaCXX/static-cast.cpp @@ -1,11 +1,11 @@ -// RUN: clang-cc -fsyntax-only -verify %s +// RUN: clang-cc -fsyntax-only -verify -faccess-control %s struct A {}; struct B : public A {}; // Single public base. struct C1 : public virtual B {}; // Single virtual base. struct C2 : public virtual B {}; struct D : public C1, public C2 {}; // Diamond -struct E : private A {}; // Single private base. +struct E : private A {}; // Single private base. expected-note 2 {{'private' inheritance specifier here}} struct F : public C1 {}; // Single path to B with virtual. struct G1 : public B {}; struct G2 : public B {}; @@ -14,6 +14,11 @@ struct H : public G1, public G2 {}; // Ambiguous path to B. enum Enum { En1, En2 }; enum Onom { On1, On2 }; +struct Co1 { operator int(); }; +struct Co2 { Co2(int); }; +struct Co3 { }; +struct Co4 { Co4(Co3); operator Co3(); }; + // Explicit implicits void t_529_2() { @@ -45,7 +50,9 @@ void t_529_2() (void)static_cast<int B::*>((int A::*)0); (void)static_cast<void (B::*)()>((void (A::*)())0); - // TODO: User-defined conversions + (void)static_cast<int>(Co1()); + (void)static_cast<Co2>(1); + (void)static_cast<Co3>(static_cast<Co4>(Co3())); // Bad code below @@ -80,11 +87,10 @@ void t_529_5_8() (void)static_cast<D&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}} (void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'struct A const *' to 'struct B *' casts away constness}} (void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'struct A const' to 'struct B &' casts away constness}} - // Accessibility is not yet tested - //(void)static_cast<E*>((A*)0); // {{static_cast from 'struct A *' to 'struct E *' is not allowed}} - //(void)static_cast<E&>(*((A*)0)); // {{static_cast from 'struct A' to 'struct E &' is not allowed}} - (void)static_cast<H*>((A*)0); // expected-error {{ambiguous static_cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} - (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous static_cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + (void)static_cast<E*>((A*)0); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}} + (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct E' due to inaccessible}} + (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} + (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}} (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'struct B *' to 'struct E *' is not allowed}} (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'struct E' cannot be initialized with a value of type 'struct B'}} diff --git a/test/SemaCXX/static-initializers.cpp b/test/SemaCXX/static-initializers.cpp index 3d92a532ae1a..a651243df7ef 100644 --- a/test/SemaCXX/static-initializers.cpp +++ b/test/SemaCXX/static-initializers.cpp @@ -1,12 +1,10 @@ // RUN: clang-cc -fsyntax-only -verify %s -int f() -{ - return 10; +int f() { + return 10; } -void g() -{ - static int a = f(); +void g() { + static int a = f(); } static int b = f(); diff --git a/test/SemaCXX/type-traits-incomplete.cpp b/test/SemaCXX/type-traits-incomplete.cpp new file mode 100644 index 000000000000..ac8ec452b93f --- /dev/null +++ b/test/SemaCXX/type-traits-incomplete.cpp @@ -0,0 +1,7 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct S; // expected-note{{forward declaration of 'struct S'}} + +void f() { + __is_pod(S); // expected-error{{incomplete type 'struct S' used in type trait expression}} +} diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp index 1a2e329b2a44..340c0ae4899b 100644 --- a/test/SemaCXX/type-traits.cpp +++ b/test/SemaCXX/type-traits.cpp @@ -7,14 +7,23 @@ struct NonPOD { NonPOD(int); }; // PODs enum Enum { EV }; struct POD { Enum e; int i; float f; NonPOD* p; }; +struct Empty {}; +typedef Empty EmptyAr[10]; typedef int Int; typedef Int IntAr[10]; class Statics { static int priv; static NonPOD np; }; +union EmptyUnion {}; +union Union { int i; float f; }; +struct HasFunc { void f (); }; +struct HasOp { void operator *(); }; +struct HasConv { operator int(); }; +struct HasAssign { void operator =(int); }; // Not PODs struct Derives : POD {}; +struct DerivesEmpty : Empty {}; struct HasCons { HasCons(int); }; -struct HasAssign { HasAssign operator =(const HasAssign&); }; +struct HasCopyAssign { HasCopyAssign operator =(const HasCopyAssign&); }; struct HasDest { ~HasDest(); }; class HasPriv { int priv; }; class HasProt { protected: int prot; }; @@ -22,6 +31,8 @@ struct HasRef { int i; int& ref; HasRef() : i(0), ref(i) {} }; struct HasNonPOD { NonPOD np; }; struct HasVirt { virtual void Virt() {}; }; typedef Derives NonPODAr[10]; +typedef HasVirt VirtAr[10]; +union NonPODUnion { int i; Derives n; }; void is_pod() { @@ -31,10 +42,17 @@ void is_pod() int t04[T(__is_pod(Int))]; int t05[T(__is_pod(IntAr))]; int t06[T(__is_pod(Statics))]; + int t07[T(__is_pod(Empty))]; + int t08[T(__is_pod(EmptyUnion))]; + int t09[T(__is_pod(Union))]; + int t10[T(__is_pod(HasFunc))]; + int t11[T(__is_pod(HasOp))]; + int t12[T(__is_pod(HasConv))]; + int t13[T(__is_pod(HasAssign))]; int t21[F(__is_pod(Derives))]; int t22[F(__is_pod(HasCons))]; - int t23[F(__is_pod(HasAssign))]; + int t23[F(__is_pod(HasCopyAssign))]; int t24[F(__is_pod(HasDest))]; int t25[F(__is_pod(HasPriv))]; int t26[F(__is_pod(HasProt))]; @@ -42,9 +60,40 @@ void is_pod() int t28[F(__is_pod(HasNonPOD))]; int t29[F(__is_pod(HasVirt))]; int t30[F(__is_pod(NonPODAr))]; + int t31[F(__is_pod(DerivesEmpty))]; + // int t32[F(__is_pod(NonPODUnion))]; +} + +typedef Empty EmptyAr[10]; +struct Bit0 { int : 0; }; +struct Bit0Cons { int : 0; Bit0Cons(); }; +struct BitOnly { int x : 3; }; +//struct DerivesVirt : virtual POD {}; + +void is_empty() +{ + int t01[T(__is_empty(Empty))]; + int t02[T(__is_empty(DerivesEmpty))]; + int t03[T(__is_empty(HasCons))]; + int t04[T(__is_empty(HasCopyAssign))]; + int t05[T(__is_empty(HasDest))]; + int t06[T(__is_empty(HasFunc))]; + int t07[T(__is_empty(HasOp))]; + int t08[T(__is_empty(HasConv))]; + int t09[T(__is_empty(HasAssign))]; + int t10[T(__is_empty(Bit0))]; + int t11[T(__is_empty(Bit0Cons))]; + + int t21[F(__is_empty(Int))]; + int t22[F(__is_empty(POD))]; + int t23[F(__is_empty(EmptyUnion))]; + int t24[F(__is_empty(EmptyAr))]; + int t25[F(__is_empty(HasRef))]; + int t26[F(__is_empty(HasVirt))]; + int t27[F(__is_empty(BitOnly))]; +// int t27[F(__is_empty(DerivesVirt))]; } -union Union { int i; float f; }; typedef Derives ClassType; void is_class() @@ -92,7 +141,7 @@ void is_enum() int t17[F(__is_enum(ClassType))]; } -struct Polymorph { virtual void f(); }; +typedef HasVirt Polymorph; struct InheritPolymorph : Polymorph {}; void is_polymorphic() @@ -109,3 +158,95 @@ void is_polymorphic() int t17[F(__is_polymorphic(ClassType))]; int t18[F(__is_polymorphic(Enum))]; } + +typedef Int& IntRef; +typedef const IntAr ConstIntAr; +typedef ConstIntAr ConstIntArAr[4]; + +struct HasCopy { + HasCopy(HasCopy& cp); +}; + +void has_trivial_default_constructor() { + int t01[T(__has_trivial_constructor(Int))]; + int t02[T(__has_trivial_constructor(IntAr))]; + int t03[T(__has_trivial_constructor(Union))]; + int t04[T(__has_trivial_constructor(UnionAr))]; + int t05[T(__has_trivial_constructor(POD))]; + int t06[T(__has_trivial_constructor(Derives))]; + int t07[T(__has_trivial_constructor(ConstIntAr))]; + int t08[T(__has_trivial_constructor(ConstIntArAr))]; + int t09[T(__has_trivial_constructor(HasDest))]; + int t10[T(__has_trivial_constructor(HasPriv))]; + int t11[F(__has_trivial_constructor(HasCons))]; + int t12[F(__has_trivial_constructor(HasRef))]; + int t13[F(__has_trivial_constructor(HasCopy))]; + int t14[F(__has_trivial_constructor(IntRef))]; + int t15[T(__has_trivial_constructor(HasCopyAssign))]; + int t16[T(__has_trivial_constructor(const Int))]; + int t17[T(__has_trivial_constructor(NonPODAr))]; + int t18[F(__has_trivial_constructor(VirtAr))]; +} + +void has_trivial_copy_constructor() { + int t01[T(__has_trivial_copy(Int))]; + int t02[T(__has_trivial_copy(IntAr))]; + int t03[T(__has_trivial_copy(Union))]; + int t04[T(__has_trivial_copy(UnionAr))]; + int t05[T(__has_trivial_copy(POD))]; + int t06[T(__has_trivial_copy(Derives))]; + int t07[T(__has_trivial_copy(ConstIntAr))]; + int t08[T(__has_trivial_copy(ConstIntArAr))]; + int t09[T(__has_trivial_copy(HasDest))]; + int t10[T(__has_trivial_copy(HasPriv))]; + int t11[T(__has_trivial_copy(HasCons))]; + int t12[T(__has_trivial_copy(HasRef))]; + int t13[F(__has_trivial_copy(HasCopy))]; + int t14[T(__has_trivial_copy(IntRef))]; + int t15[T(__has_trivial_copy(HasCopyAssign))]; + int t16[T(__has_trivial_copy(const Int))]; + int t17[F(__has_trivial_copy(NonPODAr))]; + int t18[F(__has_trivial_copy(VirtAr))]; +} + +void has_trivial_copy_assignment() { + int t01[T(__has_trivial_assign(Int))]; + int t02[T(__has_trivial_assign(IntAr))]; + int t03[T(__has_trivial_assign(Union))]; + int t04[T(__has_trivial_assign(UnionAr))]; + int t05[T(__has_trivial_assign(POD))]; + int t06[T(__has_trivial_assign(Derives))]; + int t07[F(__has_trivial_assign(ConstIntAr))]; + int t08[F(__has_trivial_assign(ConstIntArAr))]; + int t09[T(__has_trivial_assign(HasDest))]; + int t10[T(__has_trivial_assign(HasPriv))]; + int t11[T(__has_trivial_assign(HasCons))]; + int t12[T(__has_trivial_assign(HasRef))]; + int t13[T(__has_trivial_assign(HasCopy))]; + int t14[F(__has_trivial_assign(IntRef))]; + int t15[F(__has_trivial_assign(HasCopyAssign))]; + int t16[F(__has_trivial_assign(const Int))]; + int t17[F(__has_trivial_assign(NonPODAr))]; + int t18[F(__has_trivial_assign(VirtAr))]; +} + +void has_trivial_destructor() { + int t01[T(__has_trivial_destructor(Int))]; + int t02[T(__has_trivial_destructor(IntAr))]; + int t03[T(__has_trivial_destructor(Union))]; + int t04[T(__has_trivial_destructor(UnionAr))]; + int t05[T(__has_trivial_destructor(POD))]; + int t06[T(__has_trivial_destructor(Derives))]; + int t07[T(__has_trivial_destructor(ConstIntAr))]; + int t08[T(__has_trivial_destructor(ConstIntArAr))]; + int t09[F(__has_trivial_destructor(HasDest))]; + int t10[T(__has_trivial_destructor(HasPriv))]; + int t11[T(__has_trivial_destructor(HasCons))]; + int t12[T(__has_trivial_destructor(HasRef))]; + int t13[T(__has_trivial_destructor(HasCopy))]; + int t14[T(__has_trivial_destructor(IntRef))]; + int t15[T(__has_trivial_destructor(HasCopyAssign))]; + int t16[T(__has_trivial_destructor(const Int))]; + int t17[T(__has_trivial_destructor(NonPODAr))]; + int t18[T(__has_trivial_destructor(VirtAr))]; +} diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp new file mode 100644 index 000000000000..054212951338 --- /dev/null +++ b/test/SemaCXX/unknown-type-name.cpp @@ -0,0 +1,29 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// PR3990 +namespace N { + struct Wibble { + }; + + typedef Wibble foo; +} +using namespace N; + +foo::bar x; // expected-error{{no type named 'bar' in 'struct N::Wibble'}} + +void f() { + foo::bar = 4; // expected-error{{no member named 'bar' in 'struct N::Wibble'}} +} + +template<typename T> +struct A { + typedef T type; + + type f(); +}; + +template<typename T> +A<T>::type g(T t) { return t; } // expected-error{{missing 'typename'}} + +template<typename T> +A<T>::type A<T>::f() { return type(); } // expected-error{{missing 'typename'}} diff --git a/test/SemaCXX/unreachable-catch-clauses.cpp b/test/SemaCXX/unreachable-catch-clauses.cpp new file mode 100644 index 000000000000..c8b642e7ab53 --- /dev/null +++ b/test/SemaCXX/unreachable-catch-clauses.cpp @@ -0,0 +1,14 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class BaseEx {}; +class Ex1: public BaseEx {}; +typedef Ex1 Ex2; + +void f(); + +void test() +try {} +catch (BaseEx &e) { f(); } +catch (Ex1 &e) { f(); } // expected-note {{for type class Ex1 &}} +catch (Ex2 &e) { f(); } // expected-warning {{exception of type Ex2 & will be caught by earlier handler}} + diff --git a/test/SemaCXX/using-decl-1.cpp b/test/SemaCXX/using-decl-1.cpp index 2459f251deb2..37e101e221ea 100644 --- a/test/SemaCXX/using-decl-1.cpp +++ b/test/SemaCXX/using-decl-1.cpp @@ -6,3 +6,14 @@ namespace std { using ::f; inline void f() { return f(true); } } + +namespace M { + void f(float); +} + +namespace N { + using M::f; + void f(int) { } // expected-note{{previous}} + + void f(int) { } // expected-error{{redefinition}} +} diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp new file mode 100644 index 000000000000..1a53704c1e68 --- /dev/null +++ b/test/SemaCXX/using-decl-templates.cpp @@ -0,0 +1,36 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> struct A { + void f() { } + struct N { }; +}; + +template<typename T> struct B : A<T> { + using A<T>::f; + using A<T>::N; + + using A<T>::foo; // expected-error{{no member named 'foo'}} + using A<double>::f; // expected-error{{using declaration refers into 'A<double>::', which is not a base class of 'B'}} +}; + +B<int> a; // expected-note{{in instantiation of template class 'struct B<int>' requested here}} + +template<typename T> struct C : A<T> { + using A<T>::f; + + void f() { }; +}; + +template <typename T> struct D : A<T> { + using A<T>::f; + + void f(); +}; + +template<typename T> void D<T>::f() { } + +template<typename T> struct E : A<T> { + using A<T>::f; + + void g() { f(); } +}; diff --git a/test/SemaCXX/value-dependent-exprs.cpp b/test/SemaCXX/value-dependent-exprs.cpp new file mode 100644 index 000000000000..c70f895d2bf9 --- /dev/null +++ b/test/SemaCXX/value-dependent-exprs.cpp @@ -0,0 +1,47 @@ +// RUN: clang-cc -verify %s + +template <unsigned I> +class C0 { + static const int iv0 = 1 << I; + + enum { + A = I, + B = I + 1 + }; + + struct s0 { + int a : I; + int b[I]; + }; + + // FIXME: I'm unclear where the right place to handle this is. +#if 0 + void f0(int *p) { + if (p == I) { + } + } +#endif + +#if 0 + // FIXME: Not sure whether we care about these. + void f1(int *a) + __attribute__((nonnull(1 + I))) + __attribute__((constructor(1 + I))) + __attribute__((destructor(1 + I))) + __attribute__((sentinel(1 + I, 2 + I))), + __attribute__((reqd_work_group_size(1 + I, 2 + I, 3 + I))), + __attribute__((format_arg(1 + I))), + __attribute__((aligned(1 + I))), + __attribute__((regparm(1 + I))); + + typedef int int_a0 __attribute__((address_space(1 + B))); +#endif + +#if 0 + // FIXME: This doesn't work. PR4996. + int f2() { + return __builtin_choose_expr(I, 1, 2); + } +#endif + +}; diff --git a/test/SemaCXX/vararg-non-pod.cpp b/test/SemaCXX/vararg-non-pod.cpp index 1c5fe74a154d..390f58b1b7b3 100644 --- a/test/SemaCXX/vararg-non-pod.cpp +++ b/test/SemaCXX/vararg-non-pod.cpp @@ -51,6 +51,18 @@ void t4() D d; - d(10, c); // expected-warning{{Line 48: cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}} + d(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}} d(10, version); } + +class E { + E(int, ...); +}; + +void t5() +{ + C c(10); + + E e(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic constructor; call will abort at runtime}} + (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic constructor; call will abort at runtime}} +}
\ No newline at end of file diff --git a/test/SemaCXX/vector-casts.cpp b/test/SemaCXX/vector-casts.cpp new file mode 100644 index 000000000000..5b08043545fa --- /dev/null +++ b/test/SemaCXX/vector-casts.cpp @@ -0,0 +1,40 @@ +// RUN: clang-cc -fsyntax-only -verify %s +typedef int __v2si __attribute__((__vector_size__(8))); +typedef short __v4hi __attribute__((__vector_size__(8))); +typedef short __v8hi __attribute__((__vector_size__(16))); + +struct S { }; + +void f() { + __v2si v2si; + __v4hi v4hi; + __v8hi v8hi; + unsigned long long ll; + unsigned char c; + S s; + + (void)reinterpret_cast<__v2si>(v4hi); + (void)(__v2si)v4hi; + (void)reinterpret_cast<__v4hi>(v2si); + (void)(__v4hi)v2si; + (void)reinterpret_cast<unsigned long long>(v2si); + (void)(unsigned long long)v2si; + (void)reinterpret_cast<__v2si>(ll); + (void)(__v2si)(ll); + + (void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' to 'struct S' is not allowed}} + (void)(S)v2si; // expected-error {{C-style cast from '__v2si' to 'struct S' is not allowed}} + (void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'struct S' to '__v2si' is not allowed}} + (void)(__v2si)s; // expected-error {{C-style cast from 'struct S' to '__v2si' is not allowed}} + + (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}} + (void)reinterpret_cast<__v2si>(c); // expected-error {{reinterpret_cast from scalar 'unsigned char' to vector '__v2si' of different size}} + + (void)reinterpret_cast<__v8hi>(v4hi); // expected-error {{reinterpret_cast from vector '__v4hi' to vector '__v8hi' of different size}} + (void)(__v8hi)v4hi; // expected-error {{C-style cast from vector '__v4hi' to vector '__v8hi' of different size}} + (void)reinterpret_cast<__v4hi>(v8hi); // expected-error {{reinterpret_cast from vector '__v8hi' to vector '__v4hi' of different size}} + (void)(__v4hi)v8hi; // expected-error {{C-style cast from vector '__v8hi' to vector '__v4hi' of different size}} +} + + diff --git a/test/SemaCXX/warn-assignment-condition.cpp b/test/SemaCXX/warn-assignment-condition.cpp new file mode 100644 index 000000000000..3b9f3066a16b --- /dev/null +++ b/test/SemaCXX/warn-assignment-condition.cpp @@ -0,0 +1,65 @@ +// RUN: clang-cc -fsyntax-only -Wparentheses -verify %s + +struct A { + int foo(); + friend A operator+(const A&, const A&); + operator bool(); +}; + +void test() { + int x, *p; + A a, b; + + // With scalars. + if (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + if ((x = 7)) {} + do { + } while (x = 7); // expected-warning {{using the result of an assignment as a condition without parentheses}} + do { + } while ((x = 7)); + while (x = 7) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + while ((x = 7)) {} + for (; x = 7; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + for (; (x = 7); ) {} + + if (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + if ((p = p)) {} + do { + } while (p = p); // expected-warning {{using the result of an assignment as a condition without parentheses}} + do { + } while ((p = p)); + while (p = p) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + while ((p = p)) {} + for (; p = p; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + for (; (p = p); ) {} + + // Initializing variables (shouldn't warn). + if (int y = x) {} + while (int y = x) {} + if (A y = a) {} + while (A y = a) {} + + // With temporaries. + if (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + if ((x = (b+b).foo())) {} + do { + } while (x = (b+b).foo()); // expected-warning {{using the result of an assignment as a condition without parentheses}} + do { + } while ((x = (b+b).foo())); + while (x = (b+b).foo()) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + while ((x = (b+b).foo())) {} + for (; x = (b+b).foo(); ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + for (; (x = (b+b).foo()); ) {} + + // With a user-defined operator. + if (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + if ((a = b + b)) {} + do { + } while (a = b + b); // expected-warning {{using the result of an assignment as a condition without parentheses}} + do { + } while ((a = b + b)); + while (a = b + b) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + while ((a = b + b)) {} + for (; a = b + b; ) {} // expected-warning {{using the result of an assignment as a condition without parentheses}} + for (; (a = b + b); ) {} +} diff --git a/test/SemaCXX/warn-char-subscripts.cpp b/test/SemaCXX/warn-char-subscripts.cpp new file mode 100644 index 000000000000..1c06db91c3f7 --- /dev/null +++ b/test/SemaCXX/warn-char-subscripts.cpp @@ -0,0 +1,21 @@ +// RUN: clang-cc -Wchar-subscripts -fsyntax-only -verify %s + +template<typename T> +void t1() { + int array[1] = { 0 }; + T subscript = 0; + int val = array[subscript]; // expected-warning{{array subscript is of type 'char'}} +} + +template<typename T> +void t2() { + int array[1] = { 0 }; + T subscript = 0; + int val = subscript[array]; // expected-warning{{array subscript is of type 'char'}} +} + +void test() { + t1<char>(); // expected-note {{in instantiation of function template specialization 't1<char>' requested here}} + t2<char>(); // expected-note {{in instantiation of function template specialization 't2<char>' requested here}} +} + diff --git a/test/SemaCXX/warn-for-var-in-else.cpp b/test/SemaCXX/warn-for-var-in-else.cpp index 3368da223a48..f73c60689446 100644 --- a/test/SemaCXX/warn-for-var-in-else.cpp +++ b/test/SemaCXX/warn-for-var-in-else.cpp @@ -8,6 +8,7 @@ int foo() { return X; } else { do_something(X); // expected-warning{{'X' is always zero in this context}} + return 0; } } diff --git a/test/SemaCXX/warn-reorder-ctor-initialization.cpp b/test/SemaCXX/warn-reorder-ctor-initialization.cpp new file mode 100644 index 000000000000..bfce588b570a --- /dev/null +++ b/test/SemaCXX/warn-reorder-ctor-initialization.cpp @@ -0,0 +1,89 @@ +// RUN: clang-cc -fsyntax-only -Wreorder -verify %s + +struct BB {}; + +struct BB1 {}; + +class complex : public BB, BB1 { +public: + complex() : s2(1), // expected-warning {{member 's2' will be initialized after}} + s1(1) , // expected-note {{field s1}} + s3(3), // expected-warning {{member 's3' will be initialized after}} + BB1(), // expected-note {{base 'struct BB1'}} \ + // expected-warning {{base class 'struct BB1' will be initialized after}} + BB() {} // expected-note {{base 'struct BB'}} + int s1; + int s2; + int s3; +}; + + +// testing virtual bases. + + +struct V { + V(); +}; + +struct A : public virtual V { + A(); +}; + +struct B : public virtual V { + B(); +}; + +struct Diamond : public A, public B { + Diamond() : A(), B() {} +}; + + +struct C : public A, public B, private virtual V { + C() { } +}; + + +struct D : public A, public B { + D() : A(), V() { } // expected-warning {{base class 'struct A' will be initialized after}} \ + // expected-note {{base 'struct V'}} +}; + + +struct E : public A, public B, private virtual V { + E() : A(), V() { } // expected-warning {{base class 'struct A' will be initialized after}} \ + // expected-note {{base 'struct V'}} +}; + + +struct A1 { + A1(); +}; + +struct B1 { + B1(); +}; + +struct F : public A1, public B1, private virtual V { + F() : A1(), V() { } // expected-warning {{base class 'struct A1' will be initialized after}} \ + // expected-note {{base 'struct V'}} +}; + +struct X : public virtual A, virtual V, public virtual B { + X(): A(), V(), B() {} // expected-warning {{base class 'struct A' will be initialized after}} \ + // expected-note {{base 'struct V'}} +}; + +class Anon { + int c; union {int a,b;}; int d; + Anon() : c(10), b(1), d(2) {} +}; +class Anon2 { + int c; union {int a,b;}; int d; + Anon2() : c(2), + d(10), // expected-warning {{member 'd' will be initialized after}} + b(1) {} // expected-note {{field b}} +}; +class Anon3 { + union {int a,b;}; + Anon3() : b(1) {} +}; diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp new file mode 100644 index 000000000000..d8b9a00ad6de --- /dev/null +++ b/test/SemaCXX/warn-unused-variables.cpp @@ -0,0 +1,6 @@ +// RUN: clang -fsyntax-only -Wunused-variable -verify %s + +template<typename T> void f() { + T t; + t = 17; +} diff --git a/test/SemaCXX/wchar_t.cpp b/test/SemaCXX/wchar_t.cpp index fc258da7d1a6..cb85bc3ae729 100644 --- a/test/SemaCXX/wchar_t.cpp +++ b/test/SemaCXX/wchar_t.cpp @@ -7,3 +7,7 @@ void f(wchar_t p) { signed wchar_t z; // expected-warning {{'wchar_t' cannot be signed or unsigned}} ++x; } + +// PR4502 +wchar_t const c = L'c'; +int a[c == L'c' ? 1 : -1]; |