diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-03-16 16:52:15 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-03-16 16:52:15 +0000 |
commit | 4a37f65f1c1373c9956d118a012943de2f61edb0 (patch) | |
tree | 52aebaff3a47b97dbac434530524c30967468412 /test | |
parent | a16e9ac1f192503038f49e0c52edd7dcb2ce023a (diff) | |
download | src-4a37f65f1c1373c9956d118a012943de2f61edb0.tar.gz src-4a37f65f1c1373c9956d118a012943de2f61edb0.zip |
Notes
Diffstat (limited to 'test')
34 files changed, 765 insertions, 39 deletions
diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp index a06fb2e3e3c2..83b4227aa3bc 100644 --- a/test/CXX/class.access/class.friend/p1.cpp +++ b/test/CXX/class.access/class.friend/p1.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -faccess-control -verify %s // C++'0x [class.friend] p1: // A friend of a class is a function or class that is given permission to use @@ -60,3 +60,58 @@ namespace N { x.g2(); // expected-error{{no member named 'g2' in 'N::X'}} } } + +namespace test0 { + class ClassFriend { + void test(); + }; + + class MemberFriend { + void test(); + }; + + void declared_test(); + + class Class { + static void member(); // expected-note 2 {{declared private here}} + + friend class ClassFriend; + friend class UndeclaredClassFriend; + + friend void undeclared_test(); + friend void declared_test(); + friend void MemberFriend::test(); + }; + + void declared_test() { + Class::member(); + } + + void undeclared_test() { + Class::member(); + } + + void unfriended_test() { + Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}} + } + + void ClassFriend::test() { + Class::member(); + } + + void MemberFriend::test() { + Class::member(); + } + + class UndeclaredClassFriend { + void test() { + Class::member(); + } + }; + + class ClassNonFriend { + void test() { + Class::member(); // expected-error {{'member' is a private member of 'test0::Class'}} + } + }; +} diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp index 7aa614cd8b1a..15b336a4d8e6 100644 --- a/test/CXX/class.access/p4.cpp +++ b/test/CXX/class.access/p4.cpp @@ -99,16 +99,124 @@ namespace test2 { // Implicit destructor calls. namespace test3 { - class A{ + class A { private: ~A(); // expected-note 3 {{declared private here}} static A foo; }; - A a; // expected-error {{'~A' is a private member}} + A a; // expected-error {{variable of type 'test3::A' has private destructor}} A A::foo; - void foo(A param) { // expected-error {{'~A' is a private member}} - A local; // expected-error {{'~A' is a private member}} + void foo(A param) { // expected-error {{variable of type 'test3::A' has private destructor}} + A local; // expected-error {{variable of type 'test3::A' has private destructor}} + } + + template <unsigned N> class Base { ~Base(); }; // expected-note 8 {{declared private here}} + class Base2 : virtual Base<2> { ~Base2(); }; // expected-note 2 {{declared private here}} + class Base3 : virtual Base<3> { public: ~Base3(); }; + + // These don't cause diagnostics because we don't need the destructor. + class Derived0 : Base<0> { ~Derived0(); }; + class Derived1 : Base<1> { }; + + class Derived2 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \ + // expected-error {{inherited virtual base class 'Base<3>' has private destructor}} + Base<0>, // expected-error {{base class 'Base<0>' has private destructor}} + virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}} + Base2, // expected-error {{base class 'test3::Base2' has private destructor}} + virtual Base3 + { + ~Derived2() {} + }; + + class Derived3 : // expected-error {{inherited virtual base class 'Base<2>' has private destructor}} \ + // expected-error {{inherited virtual base class 'Base<3>' has private destructor}} + Base<0>, // expected-error {{base class 'Base<0>' has private destructor}} + virtual Base<1>, // expected-error {{base class 'Base<1>' has private destructor}} + Base2, // expected-error {{base class 'test3::Base2' has private destructor}} + virtual Base3 + {}; + Derived3 d3; +} + +// Conversion functions. +namespace test4 { + class Base { + private: + operator Private(); // expected-note 4 {{declared private here}} + public: + operator Public(); + }; + + class Derived1 : private Base { // expected-note 2 {{declared private here}} \ + // expected-note {{constrained by private inheritance}} + Private test1() { return *this; } // expected-error {{'operator Private' is a private member}} + Public test2() { return *this; } + }; + Private test1(Derived1 &d) { return d; } // expected-error {{'operator Private' is a private member}} \ + // expected-error {{cannot cast 'test4::Derived1' to its private base class}} + Public test2(Derived1 &d) { return d; } // expected-error {{cannot cast 'test4::Derived1' to its private base class}} \ + // expected-error {{'operator Public' is a private member}} + + + class Derived2 : public Base { + Private test1() { return *this; } // expected-error {{'operator Private' is a private member}} + Public test2() { return *this; } + }; + Private test1(Derived2 &d) { return d; } // expected-error {{'operator Private' is a private member}} + Public test2(Derived2 &d) { return d; } + + class Derived3 : private Base { // expected-note {{constrained by private inheritance here}} \ + // expected-note {{declared private here}} + public: + operator Private(); + }; + Private test1(Derived3 &d) { return d; } + Public test2(Derived3 &d) { return d; } // expected-error {{'operator Public' is a private member of 'test4::Base'}} \ + // expected-error {{cannot cast 'test4::Derived3' to its private base class}} + + class Derived4 : public Base { + public: + operator Private(); + }; + Private test1(Derived4 &d) { return d; } + Public test2(Derived4 &d) { return d; } +} + +// Implicit copy assignment operator uses. +namespace test5 { + class A { + void operator=(const A &); // expected-note 2 {{declared private here}} + }; + + class Test1 { A a; }; // expected-error {{field of type 'test5::A' has private copy assignment operator}} + void test1() { + Test1 a; + a = Test1(); + } + + class Test2 : A {}; // expected-error {{base class 'test5::A' has private copy assignment operator}} + void test2() { + Test2 a; + a = Test2(); + } +} + +// Implicit copy constructor uses. +namespace test6 { + class A { + public: A(); + private: A(const A &); // expected-note 2 {{declared private here}} + }; + + class Test1 { A a; }; // expected-error {{field of type 'test6::A' has private copy constructor}} + void test1(const Test1 &t) { + Test1 a = t; + } + + class Test2 : A {}; // expected-error {{base class 'test6::A' has private copy constructor}} + void test2(const Test2 &t) { + Test2 a = t; } } diff --git a/test/CXX/temp/temp.res/temp.local/p7.cpp b/test/CXX/temp/temp.res/temp.local/p7.cpp new file mode 100644 index 000000000000..bd05e756a19e --- /dev/null +++ b/test/CXX/temp/temp.res/temp.local/p7.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template<class T> struct A { + int B; + int f(); +}; + +template<class B> int A<B>::f() { + return B; +} diff --git a/test/CXX/temp/temp.res/temp.local/p8.cpp b/test/CXX/temp/temp.res/temp.local/p8.cpp new file mode 100644 index 000000000000..5d9d50913f36 --- /dev/null +++ b/test/CXX/temp/temp.res/temp.local/p8.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace N { + enum { C }; + template<class T> class B { + void f(T); + }; +} + +template<class C> void N::B<C>::f(C) { + C b; +} + +namespace N { + enum { D }; + namespace M { + enum { C , D }; + template<typename C> class X { + template<typename U> void f(C, U); + + template<typename D> void g(C, D) { + C c; + D d; + } + }; + + struct Y { + template<typename U> void f(U); + }; + } + + struct Y { + template<typename D> void f(D); + }; +} + +template<typename C> +template<typename D> +void N::M::X<C>::f(C, D) { + C c; + D d; +} + +template<typename C> +void N::M::Y::f(C) { + C c; +} + +template<typename D> +void N::Y::f(D) { + D d; +} + diff --git a/test/CXX/temp/temp.res/temp.local/p9.cpp b/test/CXX/temp/temp.res/temp.local/p9.cpp new file mode 100644 index 000000000000..9ca8d8877d7d --- /dev/null +++ b/test/CXX/temp/temp.res/temp.local/p9.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct A { + struct B { void f(); }; + int a; + int Y; +}; + +template<class B, class a> struct X : A { + B b; // A's B + a c; // expected-error{{unknown type name 'a'}} + + void g() { + b.g(); // expected-error{{no member named 'g' in 'A::B'}} + } +}; diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp index 70eb69641867..d8f7b52145dd 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp @@ -12,10 +12,10 @@ T X<T>::member1; template<typename T> T X<T>::member2 = 17; -// CHECK: @_ZN1XIiE7member1E = global i32 0 +// CHECK: @_ZN1XIiE7member1E = weak global i32 0 template int X<int>::member1; -// CHECK: @_ZN1XIiE7member2E = global i32 17 +// CHECK: @_ZN1XIiE7member2E = weak global i32 17 template int X<int>::member2; // For implicit instantiation of diff --git a/test/CodeGen/varargs.c b/test/CodeGen/varargs.c new file mode 100644 index 000000000000..b3dba240b559 --- /dev/null +++ b/test/CodeGen/varargs.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s + + +// PR6433 - Don't crash on va_arg(typedef). +typedef double gdouble; +void focus_changed_cb () { + __builtin_va_list pa; + double mfloat; + mfloat = __builtin_va_arg((pa), gdouble); +} + diff --git a/test/CodeGenCXX/PR6474.cpp b/test/CodeGenCXX/PR6474.cpp index 68c09c9b95d5..0b155cef8355 100644 --- a/test/CodeGenCXX/PR6474.cpp +++ b/test/CodeGenCXX/PR6474.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm +// RUN: %clang_cc1 %s -emit-llvm-only namespace test0 { template <typename T> struct X { diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp index ab9174e8f406..24d1a6739229 100644 --- a/test/CodeGenCXX/explicit-instantiation.cpp +++ b/test/CodeGenCXX/explicit-instantiation.cpp @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -o %t %s -// RUN: grep "define i32 @_ZNK4plusIillEclERKiRKl" %t | count 1 +// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -o - %s | FileCheck %s template<typename T, typename U, typename Result> struct plus { @@ -11,4 +10,5 @@ Result plus<T, U, Result>::operator()(const T& t, const U& u) const { return t + u; } +// CHECK: define weak_odr i32 @_ZNK4plusIillEclERKiRKl template struct plus<int, long, long>; diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp index cdad39852c9f..6f1ca5568ed6 100644 --- a/test/CodeGenCXX/mangle-exprs.cpp +++ b/test/CodeGenCXX/mangle-exprs.cpp @@ -30,15 +30,15 @@ namespace Casts { template <int N> T<N> f() { return T<N>(); } - // CHECK: define void @_ZN5Casts8implicitILj4EEEvPN9enable_ifIXleT_Li4EEvE4typeE + // CHECK: define weak_odr void @_ZN5Casts8implicitILj4EEEvPN9enable_ifIXleT_Li4EEvE4typeE template void implicit<4>(void*); - // CHECK: define void @_ZN5Casts6cstyleILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE + // CHECK: define weak_odr void @_ZN5Casts6cstyleILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE template void cstyle<4>(void*); - // CHECK: define void @_ZN5Casts10functionalILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE + // CHECK: define weak_odr void @_ZN5Casts10functionalILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE template void functional<4>(void*); - // CHECK: define void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE + // CHECK: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE template void static_<4>(void*); - // CHECK: define i64 @_ZN5Casts1fILi6EEENS_1TIXT_EEEv + // CHECK: define weak_odr i64 @_ZN5Casts1fILi6EEENS_1TIXT_EEEv template T<6> f<6>(); } diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp index 57f30a762ed0..22949da64ad8 100644 --- a/test/CodeGenCXX/mangle-template.cpp +++ b/test/CodeGenCXX/mangle-template.cpp @@ -82,7 +82,7 @@ namespace test7 { X(U*, typename int_c<(meta<T>::value + meta<U>::value)>::type *) { } }; - // CHECK: define void @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsrNS6_IS3_EE5valueEE4typeE + // CHECK: define weak_odr void @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsrNS6_IS3_EE5valueEE4typeE template X<int>::X(double*, float*); } @@ -101,6 +101,6 @@ namespace test8 { template<typename T> void f(int_c<meta<T>::type::value>) { } - // CHECK: define void @_ZN5test81fIiEEvNS_5int_cIXsrNS_4metaIT_E4typeE5valueEEE + // CHECK: define weak_odr void @_ZN5test81fIiEEvNS_5int_cIXsrNS_4metaIT_E4typeE5valueEEE template void f<int>(int_c<sizeof(int)>); } diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index e18ca03d1be2..8dee41beb482 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -250,26 +250,26 @@ void f() { __fill_a<int>(); } namespace Expressions { // Unary operators. -// CHECK: define void @_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i +// CHECK: define weak_odr void @_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i template <int i> void f1(int (*)[(-i) + 2]) { }; template void f1<1>(int (*)[1]); -// CHECK: define void @_ZN11Expressions2f2ILi1EEEvPApsT__i +// CHECK: define weak_odr void @_ZN11Expressions2f2ILi1EEEvPApsT__i template <int i> void f2(int (*)[+i]) { }; template void f2<1>(int (*)[1]); // Binary operators. -// CHECK: define void @_ZN11Expressions2f3ILi1EEEvPAplT_T__i +// CHECK: define weak_odr void @_ZN11Expressions2f3ILi1EEEvPAplT_T__i template <int i> void f3(int (*)[i+i]) { }; template void f3<1>(int (*)[2]); -// CHECK: define void @_ZN11Expressions2f4ILi1EEEvPAplplLi2ET_T__i +// CHECK: define weak_odr void @_ZN11Expressions2f4ILi1EEEvPAplplLi2ET_T__i template <int i> void f4(int (*)[2 + i+i]) { }; template void f4<1>(int (*)[4]); // The ternary operator. -// CHECK: define void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i +// CHECK: define weak_odr void @_ZN11Expressions2f4ILb1EEEvPAquT_Li1ELi2E_i template <bool b> void f4(int (*)[b ? 1 : 2]) { }; template void f4<true>(int (*)[1]); } @@ -305,7 +305,7 @@ template<typename T, typename = Policy<P, true> > class Alloc T *allocate(int, const void*) { return 0; } }; -// CHECK: define i8* @_ZN6PR58615AllocIcNS_6PolicyINS_1PELb1EEEE8allocateEiPKv +// CHECK: define weak_odr i8* @_ZN6PR58615AllocIcNS_6PolicyINS_1PELb1EEEE8allocateEiPKv template class Alloc<char>; } @@ -369,7 +369,7 @@ namespace test0 { namespace test1 { template<typename T> struct X { }; template<template<class> class Y, typename T> void f(Y<T>) { } - // CHECK: define void @_ZN5test11fINS_1XEiEEvT_IT0_E + // CHECK: define weak_odr void @_ZN5test11fINS_1XEiEEvT_IT0_E template void f(X<int>); } @@ -399,10 +399,10 @@ namespace test3 { //template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; } //template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; } - // define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path11pERS2_( + // define weak_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path11pERS2_( template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; } - // define linkonce_odr double @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path21pERS2_( + // define weak_odr double @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path21pERS2_( template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; } Derived obj; @@ -414,3 +414,42 @@ namespace test3 { get_p_2(obj); } } + +// CHECK: define void @_ZN5test41gEPNS_3zedIXadL_ZNS_3foo3barEEEEE +namespace test4 { + struct foo { int bar; }; + template <int (foo::*)> + struct zed {}; + void g(zed<&foo::bar>*) + {} +} +// CHECK: define void @_ZN5test51gEPNS_3zedIXadL_ZNS_3foo3barEEEEE +namespace test5 { + struct foo { static int bar; }; + template <int *> + struct zed {}; + void g(zed<&foo::bar>*) + {} +} +// CHECK: define void @_ZN5test61gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE +namespace test6 { + struct foo { int bar(); }; + template <int (foo::*)()> + struct zed {}; + void g(zed<&foo::bar>*) + {} +} +// CHECK: define void @_ZN5test71gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE +namespace test7 { + struct foo { static int bar(); }; + template <int (*f)()> + struct zed {}; + void g(zed<&foo::bar>*) + {} +} +// CHECK: define weak_odr void @_ZN5test81AILZNS_1B5valueEEE3incEv +namespace test8 { + template <int &counter> class A { void inc() { counter++; } }; + class B { static int value; }; + template class A<B::value>; +} diff --git a/test/CodeGenCXX/member-templates.cpp b/test/CodeGenCXX/member-templates.cpp index 355ba20e171f..bcf1187e623f 100644 --- a/test/CodeGenCXX/member-templates.cpp +++ b/test/CodeGenCXX/member-templates.cpp @@ -15,8 +15,8 @@ struct B { template<typename T> B::B(T) {} -// CHECK: define void @_ZN1BC1IiEET_(%struct.B* %this, i32) -// CHECK: define void @_ZN1BC2IiEET_(%struct.B* %this, i32) +// CHECK: define weak_odr void @_ZN1BC1IiEET_(%struct.B* %this, i32) +// CHECK: define weak_odr void @_ZN1BC2IiEET_(%struct.B* %this, i32) template B::B(int); template<typename T> diff --git a/test/CodeGenCXX/template-linkage.cpp b/test/CodeGenCXX/template-linkage.cpp index 5d573d6e829b..ccd61a7bbe30 100644 --- a/test/CodeGenCXX/template-linkage.cpp +++ b/test/CodeGenCXX/template-linkage.cpp @@ -6,19 +6,19 @@ template<typename T> struct A { // Explicit instantiations have external linkage. -// CHECK: define void @_ZN1AIiE1gEv( +// CHECK: define weak_odr void @_ZN1AIiE1gEv( template void A<int>::g(); -// CHECK: define void @_ZN1AIfE1fEf( -// CHECK: define void @_ZN1AIfE1gEv( +// CHECK: define weak_odr void @_ZN1AIfE1fEf( +// CHECK: define weak_odr void @_ZN1AIfE1gEv( // FIXME: This should also emit the vtable. template struct A<float>; -// CHECK: define void @_Z1fIiEvT_ +// CHECK: define weak_odr void @_Z1fIiEvT_ template <typename T> void f(T) { } template void f<int>(int); -// CHECK: define void @_Z1gIiEvT_ +// CHECK: define weak_odr void @_Z1gIiEvT_ template <typename T> inline void g(T) { } template void g<int>(int); diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp index 3b624afd0ad1..cd0cf77f53b2 100644 --- a/test/CodeGenCXX/temporaries.cpp +++ b/test/CodeGenCXX/temporaries.cpp @@ -256,7 +256,7 @@ namespace PR6199 { struct B { operator A(); }; - // CHECK: define void @_ZN6PR61992f2IiEENS_1AET_ + // CHECK: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_ template<typename T> A f2(T) { B b; // CHECK: call void @_ZN6PR61991BcvNS_1AEEv diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index 5c783f1f23dc..f11ae345cc7b 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -698,6 +698,65 @@ struct C : A, B { // CHECK-NEXT: 22 | void Test18::D::f() // CHECK-NEXT: [this adjustment: -8 non-virtual, -32 vcall offset offset] // CHECK-NEXT: 23 | [unused] void Test18::C::g() + +// CHECK: Construction vtable for ('Test18::B', 0) in 'Test18::D' (7 entries). +// CHECK-NEXT: 0 | vbase_offset (0) +// CHECK-NEXT: 1 | vcall_offset (0) +// CHECK-NEXT: 2 | vcall_offset (0) +// CHECK-NEXT: 3 | offset_to_top (0) +// CHECK-NEXT: 4 | Test18::B RTTI +// CHECK-NEXT: -- (Test18::A, 0) vtable address -- +// CHECK-NEXT: -- (Test18::B, 0) vtable address -- +// CHECK-NEXT: 5 | void Test18::B::f() +// CHECK-NEXT: 6 | void Test18::A::g() + +// CHECK: Construction vtable for ('Test18::C', 8) in 'Test18::D' (20 entries). +// CHECK-NEXT: 0 | vcall_offset (0) +// CHECK-NEXT: 1 | vcall_offset (0) +// CHECK-NEXT: 2 | vbase_offset (-8) +// CHECK-NEXT: 3 | offset_to_top (0) +// CHECK-NEXT: 4 | Test18::C RTTI +// CHECK-NEXT: -- (Test18::A, 8) vtable address -- +// CHECK-NEXT: -- (Test18::C, 8) vtable address -- +// CHECK-NEXT: 5 | void Test18::A::f() +// CHECK-NEXT: 6 | void Test18::C::g() +// CHECK-NEXT: 7 | vbase_offset (-16) +// CHECK-NEXT: 8 | vcall_offset (-8) +// CHECK-NEXT: 9 | vcall_offset (0) +// CHECK-NEXT: 10 | offset_to_top (-8) +// CHECK-NEXT: 11 | Test18::C RTTI +// CHECK-NEXT: -- (Test18::A, 16) vtable address -- +// CHECK-NEXT: -- (Test18::B, 16) vtable address -- +// CHECK-NEXT: 12 | void Test18::B::f() +// CHECK-NEXT: 13 | [unused] void Test18::C::g() +// CHECK-NEXT: 14 | vcall_offset (8) +// CHECK-NEXT: 15 | vcall_offset (16) +// CHECK-NEXT: 16 | offset_to_top (8) +// CHECK-NEXT: 17 | Test18::C RTTI +// CHECK-NEXT: -- (Test18::A, 0) vtable address -- +// CHECK-NEXT: 18 | void Test18::B::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-NEXT: 19 | void Test18::C::g() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] + +// CHECK: Construction vtable for ('Test18::B', 16) in 'Test18::D' (13 entries). +// CHECK-NEXT: 0 | vbase_offset (-16) +// CHECK-NEXT: 1 | vcall_offset (-16) +// CHECK-NEXT: 2 | vcall_offset (0) +// CHECK-NEXT: 3 | offset_to_top (0) +// CHECK-NEXT: 4 | Test18::B RTTI +// CHECK-NEXT: -- (Test18::A, 16) vtable address -- +// CHECK-NEXT: -- (Test18::B, 16) vtable address -- +// CHECK-NEXT: 5 | void Test18::B::f() +// CHECK-NEXT: 6 | [unused] void Test18::A::g() +// CHECK-NEXT: 7 | vcall_offset (0) +// CHECK-NEXT: 8 | vcall_offset (16) +// CHECK-NEXT: 9 | offset_to_top (16) +// CHECK-NEXT: 10 | Test18::B RTTI +// CHECK-NEXT: -- (Test18::A, 0) vtable address -- +// CHECK-NEXT: 11 | void Test18::B::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-NEXT: 12 | void Test18::A::g() struct D : virtual B, virtual C, virtual A { virtual void f(); @@ -827,6 +886,13 @@ class E : virtual C { }; // CHECK-NEXT: -- (Test21::C, 8) vtable address -- // CHECK-NEXT: -- (Test21::E, 8) vtable address -- // CHECK-NEXT: 15 | [unused] void Test21::F::f() +// +// CHECK: Virtual base offset offsets for 'Test21::F'. +// CHECK-NEXT: Test21::A | -32 +// CHECK-NEXT: Test21::B | -40 +// CHECK-NEXT: Test21::C | -48 +// CHECK-NEXT: Test21::D | -56 +// CHECK-NEXT: Test21::E | -64 class F : virtual D, virtual E { virtual void f(); }; @@ -1091,3 +1157,130 @@ class D : virtual B, virtual C { void D::d() { } } + +namespace Test27 { + +// Test that we don't generate a secondary vtable for C in the D-in-E vtable, since +// C doesn't have any virtual bases. + +struct A { + virtual void a(); +}; + +struct B { + virtual void b(); +}; + +struct C { + virtual void c(); +}; + +struct D : A, virtual B, C { + virtual void d(); +}; + +// CHECK: Vtable for 'Test27::E' (13 entries). +// CHECK-NEXT: 0 | vbase_offset (16) +// CHECK-NEXT: 1 | offset_to_top (0) +// CHECK-NEXT: 2 | Test27::E RTTI +// CHECK-NEXT: -- (Test27::A, 0) vtable address -- +// CHECK-NEXT: -- (Test27::D, 0) vtable address -- +// CHECK-NEXT: -- (Test27::E, 0) vtable address -- +// CHECK-NEXT: 3 | void Test27::A::a() +// CHECK-NEXT: 4 | void Test27::D::d() +// CHECK-NEXT: 5 | void Test27::E::e() +// CHECK-NEXT: 6 | offset_to_top (-8) +// CHECK-NEXT: 7 | Test27::E RTTI +// CHECK-NEXT: -- (Test27::C, 8) vtable address -- +// CHECK-NEXT: 8 | void Test27::C::c() +// CHECK-NEXT: 9 | vcall_offset (0) +// CHECK-NEXT: 10 | offset_to_top (-16) +// CHECK-NEXT: 11 | Test27::E RTTI +// CHECK-NEXT: -- (Test27::B, 16) vtable address -- +// CHECK-NEXT: 12 | void Test27::B::b() + +// CHECK: Construction vtable for ('Test27::D', 0) in 'Test27::E' (9 entries). +// CHECK-NEXT: 0 | vbase_offset (16) +// CHECK-NEXT: 1 | offset_to_top (0) +// CHECK-NEXT: 2 | Test27::D RTTI +// CHECK-NEXT: -- (Test27::A, 0) vtable address -- +// CHECK-NEXT: -- (Test27::D, 0) vtable address -- +// CHECK-NEXT: 3 | void Test27::A::a() +// CHECK-NEXT: 4 | void Test27::D::d() +// CHECK-NEXT: 5 | vcall_offset (0) +// CHECK-NEXT: 6 | offset_to_top (-16) +// CHECK-NEXT: 7 | Test27::D RTTI +// CHECK-NEXT: -- (Test27::B, 16) vtable address -- +// CHECK-NEXT: 8 | void Test27::B::b() +struct E : D { + virtual void e(); +}; +void E::e() { } + +} + +namespace Test28 { + +// Check that we do include the vtable for B in the D-in-E construction vtable, since +// B is a base class of a virtual base (C). + +struct A { + virtual void a(); +}; + +struct B { + virtual void b(); +}; + +struct C : A, B { + virtual void c(); +}; + +struct D : virtual C { +}; + +// CHECK: Vtable for 'Test28::E' (14 entries). +// CHECK-NEXT: 0 | vbase_offset (8) +// CHECK-NEXT: 1 | offset_to_top (0) +// CHECK-NEXT: 2 | Test28::E RTTI +// CHECK-NEXT: -- (Test28::D, 0) vtable address -- +// CHECK-NEXT: -- (Test28::E, 0) vtable address -- +// CHECK-NEXT: 3 | void Test28::E::e() +// CHECK-NEXT: 4 | vcall_offset (8) +// CHECK-NEXT: 5 | vcall_offset (0) +// CHECK-NEXT: 6 | vcall_offset (0) +// CHECK-NEXT: 7 | offset_to_top (-8) +// CHECK-NEXT: 8 | Test28::E RTTI +// CHECK-NEXT: -- (Test28::A, 8) vtable address -- +// CHECK-NEXT: -- (Test28::C, 8) vtable address -- +// CHECK-NEXT: 9 | void Test28::A::a() +// CHECK-NEXT: 10 | void Test28::C::c() +// CHECK-NEXT: 11 | offset_to_top (-16) +// CHECK-NEXT: 12 | Test28::E RTTI +// CHECK-NEXT: -- (Test28::B, 16) vtable address -- +// CHECK-NEXT: 13 | void Test28::B::b() + +// CHECK: Construction vtable for ('Test28::D', 0) in 'Test28::E' (13 entries). +// CHECK-NEXT: 0 | vbase_offset (8) +// CHECK-NEXT: 1 | offset_to_top (0) +// CHECK-NEXT: 2 | Test28::D RTTI +// CHECK-NEXT: -- (Test28::D, 0) vtable address -- +// CHECK-NEXT: 3 | vcall_offset (8) +// CHECK-NEXT: 4 | vcall_offset (0) +// CHECK-NEXT: 5 | vcall_offset (0) +// CHECK-NEXT: 6 | offset_to_top (-8) +// CHECK-NEXT: 7 | Test28::D RTTI +// CHECK-NEXT: -- (Test28::A, 8) vtable address -- +// CHECK-NEXT: -- (Test28::C, 8) vtable address -- +// CHECK-NEXT: 8 | void Test28::A::a() +// CHECK-NEXT: 9 | void Test28::C::c() +// CHECK-NEXT: 10 | offset_to_top (-16) +// CHECK-NEXT: 11 | Test28::D RTTI +// CHECK-NEXT: -- (Test28::B, 16) vtable address -- +// CHECK-NEXT: 12 | void Test28::B::b() +struct E : D { + virtual void e(); +}; +void E::e() { } + +} diff --git a/test/PCH/changed-files.c b/test/PCH/changed-files.c new file mode 100644 index 000000000000..36453c48e716 --- /dev/null +++ b/test/PCH/changed-files.c @@ -0,0 +1,11 @@ +const char *s0 = m0; + +// RUN: echo '#define m0 ""' > %t.h +// RUN: %clang_cc1 -emit-pch -o %t.h.pch %t.h +// RUN: echo '' > %t.h +// RUN: not %clang_cc1 -include-pch %t.h.pch %s 2>&1 | grep "size of file" + +// RUN: echo '#define m0 000' > %t.h +// RUN: %clang_cc1 -emit-pch -o %t.h.pch %t.h +// RUN: echo '' > %t.h +// RUN: not %clang_cc1 -include-pch %t.h.pch %s 2>&1 | grep "size of file" diff --git a/test/Parser/missing-end.m b/test/Parser/missing-end.m new file mode 100644 index 000000000000..fb264610aecb --- /dev/null +++ b/test/Parser/missing-end.m @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface AAA +{ +} +@ x// expected-error{{expected an Objective-C directive after '@'}} +// expected-error{{missing @end}} diff --git a/test/Rewriter/rewrite-local-externs-in-block.mm b/test/Rewriter/rewrite-local-externs-in-block.mm new file mode 100644 index 000000000000..d1a56a89ee58 --- /dev/null +++ b/test/Rewriter/rewrite-local-externs-in-block.mm @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp +// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp +// radar 7735987 + +extern "C" int printf(const char*, ...); + +void bar(void (^block)()) { + block(); +} + +int main() { + static int myArr[3] = {1, 2, 3}; + printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]); + + bar(^{ + printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]); + myArr[0] = 42; + myArr[2] = 100; + printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]); + }); + + printf ("%d %d %d\n", myArr[0], myArr[1], myArr[2]); +} diff --git a/test/Rewriter/rewrite-super-message.mm b/test/Rewriter/rewrite-super-message.mm new file mode 100644 index 000000000000..036aa1bb3186 --- /dev/null +++ b/test/Rewriter/rewrite-super-message.mm @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp +// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"id=struct objc_object *" -D"Class=struct objc_class *" -D"SEL=void*" -D"__declspec(X)=" -emit-llvm -o - %t-rw.cpp | FileCheck %t-rw.cpp +// radar 7738453 + +void *sel_registerName(const char *); + +@interface __NSCFType +@end + +@interface __NSCFString : __NSCFType +- (const char *)UTF8String; +@end + +@implementation __NSCFString +- (const char *)UTF8String { + return (const char *)[super UTF8String]; +} +@end + +// CHECK: call %struct.objc_class* @class_getSuperclass diff --git a/test/Sema/compare.c b/test/Sema/compare.c index 2821a935c3c7..7c8c36f0c145 100644 --- a/test/Sema/compare.c +++ b/test/Sema/compare.c @@ -274,3 +274,11 @@ void test4() { if (value < (unsigned long) &ptr4) // expected-warning {{comparison of integers of different signs}} return; } + +// PR4807 +int test5(unsigned int x) { + return (x < 0) // expected-warning {{comparison of unsigned expression < 0 is always false}} + && (0 > x) // expected-warning {{comparison of 0 > unsigned expression is always false}} + && (x >= 0) // expected-warning {{comparison of unsigned expression >= 0 is always true}} + && (0 <= x); // expected-warning {{comparison of 0 <= unsigned expression is always true}} +} diff --git a/test/Sema/missing-field-initializers.c b/test/Sema/missing-field-initializers.c new file mode 100644 index 000000000000..828191462444 --- /dev/null +++ b/test/Sema/missing-field-initializers.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-field-initializers %s + +// This was PR4808. + +struct Foo { int a, b; }; + +struct Foo foo0 = { 1 }; // expected-warning {{missing field 'b' initializer}} +struct Foo foo1 = { .a = 1 }; // designator avoids MFI warning +struct Foo foo2 = { .b = 1 }; // designator avoids MFI warning + +struct Foo bar0[] = { + { 1,2 }, + { 1 }, // expected-warning {{missing field 'b' initializer}} + { 1,2 } +}; + +struct Foo bar1[] = { + 1, 2, + 1, 2, + 1 +}; // expected-warning {{missing field 'b' initializer}} + +struct One { int a; int b; }; +struct Two { float c; float d; float e; }; + +struct Three { + union { + struct One one; + struct Two two; + } both; +}; + +struct Three t0 = { + { .one = { 1, 2 } } +}; +struct Three t1 = { + { .two = { 1.0f, 2.0f, 3.0f } } +}; + +struct Three data[] = { + { { .one = { 1, 2 } } }, + { { .one = { 1 } } }, // expected-warning {{missing field 'b' initializer}} + { { .two = { 1.0f, 2.0f, 3.0f } } }, + { { .two = { 1.0f, 2.0f } } } // expected-warning {{missing field 'e' initializer}} +}; + +struct { int:5; int a; int:5; int b; int:5 } noNamedImplicit[] = { + { 1, 2 }, + { 1 } // expected-warning {{missing field 'b' initializer}} +}; diff --git a/test/Sema/overloadable.c b/test/Sema/overloadable.c index ff631ed9c85e..28c3e4cf8c90 100644 --- a/test/Sema/overloadable.c +++ b/test/Sema/overloadable.c @@ -50,4 +50,13 @@ void test_promote(short* sp) { promote(sp); // expected-error{{call to unavailable function 'promote'}} } - +// PR6600 +typedef double Double; +typedef Double DoubleVec __attribute__((vector_size(16))); +typedef int Int; +typedef Int IntVec __attribute__((vector_size(16))); +double magnitude(DoubleVec) __attribute__((__overloadable__)); +double magnitude(IntVec) __attribute__((__overloadable__)); +double test_p6600(DoubleVec d) { + return magnitude(d) * magnitude(d); +} diff --git a/test/Sema/return.c b/test/Sema/return.c index 5d1c97f2a2ef..3ab23f4f8f8e 100644 --- a/test/Sema/return.c +++ b/test/Sema/return.c @@ -1,4 +1,4 @@ -// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wno-unreachable-code +// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wno-unreachable-code -Wno-unused-value // clang emits the following warning by default. // With GCC, -pedantic, -Wreturn-type or -Wall are required to produce the diff --git a/test/Sema/warn-unused-value.c b/test/Sema/warn-unused-value.c new file mode 100644 index 000000000000..2e0fa54effbf --- /dev/null +++ b/test/Sema/warn-unused-value.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s + +int i = 0; +int j = 0; + +void foo(); + +// PR4806 +void pr4806() { + 1,foo(); // expected-warning {{expression result unused}} + + // other + foo(); + i; // expected-warning {{expression result unused}} + + i,foo(); // expected-warning {{expression result unused}} + foo(),i; // expected-warning {{expression result unused}} + + i,j,foo(); // expected-warning {{expression result unused}} + i,foo(),j; // expected-warning {{expression result unused}} + foo(),i,j; // expected-warning {{expression result unused}} + + i++; + + i++,foo(); + foo(),i++; + + i++,j,foo(); // expected-warning {{expression result unused}} + i++,foo(),j; // expected-warning {{expression result unused}} + foo(),i++,j; // expected-warning {{expression result unused}} + + i,j++,foo(); // expected-warning {{expression result unused}} + i,foo(),j++; // expected-warning {{expression result unused}} + foo(),i,j++; // expected-warning {{expression result unused}} + + i++,j++,foo(); + i++,foo(),j++; + foo(),i++,j++; + + {}; + ({}); + ({}),foo(); + foo(),({}); + + (int)1U; // expected-warning {{expression result unused}} + (void)1U; + + // pointer to volatile has side effect (thus no warning) + int* pi = &i; + volatile int* pj = &j; + *pi; // expected-warning {{expression result unused}} + *pj; +} diff --git a/test/Sema/warn-write-strings.c b/test/Sema/warn-write-strings.c new file mode 100644 index 000000000000..938f0be7721f --- /dev/null +++ b/test/Sema/warn-write-strings.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wwrite-strings %s + +// PR4804 +char* x = "foo"; // expected-warning {{initializing 'char const [4]' discards qualifiers, expected 'char *'}} diff --git a/test/SemaCXX/PR6562.cpp b/test/SemaCXX/PR6562.cpp new file mode 100644 index 000000000000..854d9b058bc3 --- /dev/null +++ b/test/SemaCXX/PR6562.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct X { ~X(); }; +template <typename T> +struct A { + struct B { X x; }; + struct C : public B { + C() : B() { } + }; +}; diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp index 81f68392d85a..4243c1c0ead4 100644 --- a/test/SemaCXX/decl-expr-ambiguity.cpp +++ b/test/SemaCXX/decl-expr-ambiguity.cpp @@ -10,7 +10,7 @@ void f() { int(a)++; // expected-error {{expression is not assignable}} __extension__ int(a)++; // expected-error {{expression is not assignable}} __typeof(int)(a,5)<<a; // expected-error {{function-style cast to a builtin type can only take one argument}} - void(a), ++a; // expected-warning {{expression result unused}} + void(a), ++a; if (int(a)+1) {} for (int(a)+1;;) {} // expected-warning {{expression result unused}} a = sizeof(int()+1); diff --git a/test/SemaCXX/warn-unused-value.cpp b/test/SemaCXX/warn-unused-value.cpp new file mode 100644 index 000000000000..775c3cf01f24 --- /dev/null +++ b/test/SemaCXX/warn-unused-value.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s + +// PR4806 +namespace test0 { + class Box { + public: + int i; + volatile int j; + }; + + void doit() { + // pointer to volatile has side effect (thus no warning) + Box* box = new Box; + box->i; // expected-warning {{expression result unused}} + box->j; + } +} diff --git a/test/SemaObjC/duplicate-property.m b/test/SemaObjC/duplicate-property.m new file mode 100644 index 000000000000..bc1fe71a1546 --- /dev/null +++ b/test/SemaObjC/duplicate-property.m @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface Foo { + id x; +} +@property (nonatomic, retain) id x; // expected-note{{property declared here}} +@property (nonatomic, retain) id x; // expected-error{{property has a previous declaration}} +@end diff --git a/test/SemaObjC/warn-write-strings.m b/test/SemaObjC/warn-write-strings.m new file mode 100644 index 000000000000..938f0be7721f --- /dev/null +++ b/test/SemaObjC/warn-write-strings.m @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wwrite-strings %s + +// PR4804 +char* x = "foo"; // expected-warning {{initializing 'char const [4]' discards qualifiers, expected 'char *'}} diff --git a/test/SemaObjCXX/objc-pointer-conv.mm b/test/SemaObjCXX/objc-pointer-conv.mm index c03e3aaad3db..144bda4390d5 100644 --- a/test/SemaObjCXX/objc-pointer-conv.mm +++ b/test/SemaObjCXX/objc-pointer-conv.mm @@ -24,3 +24,15 @@ void RandomFunc(CFMDRef theDict, const void *key, const void *value); RandomFunc((CFMDRef)dict, key, objects[3]); } @end + +@interface I +- (void) Meth : (I*) Arg; +@end + +void Func (I* arg); // expected-note {{candidate function not viable: no known conversion from 'I const *' to 'I *' for 1st argument}} + +void foo(const I *p, I* sel) { + [sel Meth : p]; // expected-error {{incompatible type sending 'I const *', expected 'I *'}} + Func(p); // expected-error {{no matching function for call to 'Func'}} +} + diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp index 7b4c53cfe0d7..6e0d71159004 100644 --- a/test/SemaTemplate/instantiate-function-1.cpp +++ b/test/SemaTemplate/instantiate-function-1.cpp @@ -214,3 +214,9 @@ template<typename T> struct X; template<typename T> struct Y : public X<T> { Y& x() { return *this; } }; + +// Make sure our assertions don't get too uppity. +namespace test0 { + template <class T> class A { void foo(T array[10]); }; + template class A<int>; +} diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp index 8df808d2569a..59df3c22aa1c 100644 --- a/test/SemaTemplate/virtual-member-functions.cpp +++ b/test/SemaTemplate/virtual-member-functions.cpp @@ -36,10 +36,10 @@ struct Base { template<typename T> struct Derived : Base<T> { - virtual void foo() { } // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}} + virtual void foo() { } }; -template struct Derived<int>; +template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}} template<typename T> struct HasOutOfLineKey { |