diff options
Diffstat (limited to 'clang/test/SemaTemplate/instantiate-expr-4.cpp')
-rw-r--r-- | clang/test/SemaTemplate/instantiate-expr-4.cpp | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/instantiate-expr-4.cpp b/clang/test/SemaTemplate/instantiate-expr-4.cpp new file mode 100644 index 0000000..d95ccfe --- /dev/null +++ b/clang/test/SemaTemplate/instantiate-expr-4.cpp @@ -0,0 +1,354 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s + +// --------------------------------------------------------------------- +// C++ Functional Casts +// --------------------------------------------------------------------- +template<int N> +struct ValueInit0 { + int f() { + return int(); + } +}; + +template struct ValueInit0<5>; + +template<int N> +struct FunctionalCast0 { + int f() { + return int(N); + } +}; + +template struct FunctionalCast0<5>; + +struct X { // expected-note 3 {{candidate constructor (the implicit copy constructor)}} + X(int, int); // expected-note 3 {{candidate constructor}} +}; + +template<int N, int M> +struct BuildTemporary0 { + X f() { + return X(N, M); + } +}; + +template struct BuildTemporary0<5, 7>; + +template<int N, int M> +struct Temporaries0 { + void f() { + (void)X(N, M); + } +}; + +template struct Temporaries0<5, 7>; + +// Ensure that both the constructor and the destructor are instantiated by +// checking for parse errors from each. +template<int N> struct BadX { + BadX() { int a[-N]; } // expected-error {{array with a negative size}} + ~BadX() { int a[-N]; } // expected-error {{array with a negative size}} +}; + +template<int N> +struct PR6671 { + void f() { (void)BadX<1>(); } // expected-note 2 {{instantiation}} +}; +template struct PR6671<1>; + +// --------------------------------------------------------------------- +// new/delete expressions +// --------------------------------------------------------------------- +struct Y { }; + +template<typename T> +struct New0 { + T* f(bool x) { + if (x) + return new T; // expected-error{{no matching}} + else + return new T(); + } +}; + +template struct New0<int>; +template struct New0<Y>; +template struct New0<X>; // expected-note{{instantiation}} + +template<typename T, typename Arg1> +struct New1 { + T* f(bool x, Arg1 a1) { + return new T(a1); // expected-error{{no matching}} + } +}; + +template struct New1<int, float>; +template struct New1<Y, Y>; +template struct New1<X, Y>; // expected-note{{instantiation}} + +template<typename T, typename Arg1, typename Arg2> +struct New2 { + T* f(bool x, Arg1 a1, Arg2 a2) { + return new T(a1, a2); // expected-error{{no matching}} + } +}; + +template struct New2<X, int, float>; +template struct New2<X, int, int*>; // expected-note{{instantiation}} +// FIXME: template struct New2<int, int, float>; + +// PR5833 +struct New3 { + New3(); + + void *operator new[](__SIZE_TYPE__) __attribute__((unavailable)); // expected-note{{explicitly made unavailable}} +}; + +template<class C> +void* object_creator() { + return new C(); // expected-error{{call to unavailable function 'operator new[]'}} +} + +template void *object_creator<New3[4]>(); // expected-note{{instantiation}} + +template<typename T> +struct Delete0 { + void f(T t) { + delete t; // expected-error{{cannot delete}} + ::delete [] t; // expected-error{{cannot delete}} + } +}; + +template struct Delete0<int*>; +template struct Delete0<X*>; +template struct Delete0<int>; // expected-note{{instantiation}} + +namespace PR5755 { + template <class T> + void Foo() { + char* p = 0; + delete[] p; + } + + void Test() { + Foo<int>(); + } +} + +namespace PR10480 { + template<typename T> + struct X { + X(); + ~X() { + T *ptr = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} + } + }; + + template<typename T> + void f() { + new X<int>[1]; // expected-note{{in instantiation of member function 'PR10480::X<int>::~X' requested here}} + } + + template void f<int>(); +} + +// --------------------------------------------------------------------- +// throw expressions +// --------------------------------------------------------------------- +template<typename T> +struct Throw1 { + void f(T t) { + throw; + throw t; // expected-error{{incomplete type}} + } +}; + +struct Incomplete; // expected-note 2{{forward}} + +template struct Throw1<int>; +template struct Throw1<int*>; +template struct Throw1<Incomplete*>; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// typeid expressions +// --------------------------------------------------------------------- + +namespace std { + class type_info; +} + +template<typename T> +struct TypeId0 { + const std::type_info &f(T* ptr) { + if (ptr) + return typeid(ptr); + else + return typeid(T); // expected-error{{'typeid' of incomplete type 'Incomplete'}} + } +}; + +struct Abstract { + virtual void f() = 0; +}; + +template struct TypeId0<int>; +template struct TypeId0<Incomplete>; // expected-note{{instantiation of member function}} +template struct TypeId0<Abstract>; + +// --------------------------------------------------------------------- +// type traits +// --------------------------------------------------------------------- +template<typename T> +struct is_pod { + static const bool value = __is_pod(T); +}; + +static int is_pod0[is_pod<X>::value? -1 : 1]; +static int is_pod1[is_pod<Y>::value? 1 : -1]; + +// --------------------------------------------------------------------- +// initializer lists +// --------------------------------------------------------------------- +template<typename T, typename Val1> +struct InitList1 { + void f(Val1 val1) { + T x = { val1 }; + } +}; + +struct APair { + int *x; + const float *y; +}; + +template struct InitList1<int[1], float>; +template struct InitList1<APair, int*>; + +template<typename T, typename Val1, typename Val2> +struct InitList2 { + void f(Val1 val1, Val2 val2) { + T x = { val1, val2 }; // expected-error{{cannot initialize}} + } +}; + +template struct InitList2<APair, int*, float*>; +template struct InitList2<APair, int*, double*>; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// member references +// --------------------------------------------------------------------- +template<typename T, typename Result> +struct DotMemRef0 { + void f(T t) { + Result result = t.m; // expected-error{{non-const lvalue reference to type}} + } +}; + +struct MemInt { + int m; +}; + +struct InheritsMemInt : MemInt { }; + +struct MemIntFunc { + static int m(int); +}; + +template struct DotMemRef0<MemInt, int&>; +template struct DotMemRef0<InheritsMemInt, int&>; +template struct DotMemRef0<MemIntFunc, int (*)(int)>; +template struct DotMemRef0<MemInt, float&>; // expected-note{{instantiation}} + +template<typename T, typename Result> +struct ArrowMemRef0 { + void f(T t) { + Result result = t->m; // expected-error 2{{non-const lvalue reference}} + } +}; + +template<typename T> +struct ArrowWrapper { + T operator->(); +}; + +template struct ArrowMemRef0<MemInt*, int&>; +template struct ArrowMemRef0<InheritsMemInt*, int&>; +template struct ArrowMemRef0<MemIntFunc*, int (*)(int)>; +template struct ArrowMemRef0<MemInt*, float&>; // expected-note{{instantiation}} + +template struct ArrowMemRef0<ArrowWrapper<MemInt*>, int&>; +template struct ArrowMemRef0<ArrowWrapper<InheritsMemInt*>, int&>; +template struct ArrowMemRef0<ArrowWrapper<MemIntFunc*>, int (*)(int)>; +template struct ArrowMemRef0<ArrowWrapper<MemInt*>, float&>; // expected-note{{instantiation}} +template struct ArrowMemRef0<ArrowWrapper<ArrowWrapper<MemInt*> >, int&>; + +struct UnresolvedMemRefArray { + int f(int); + int f(char); +}; +UnresolvedMemRefArray Arr[10]; +template<typename U> int UnresolvedMemRefArrayT(U u) { + return Arr->f(u); +} +template int UnresolvedMemRefArrayT<int>(int); + +// FIXME: we should be able to return a MemInt without the reference! +MemInt &createMemInt(int); + +template<int N> +struct NonDepMemberExpr0 { + void f() { + createMemInt(N).m = N; + } +}; + +template struct NonDepMemberExpr0<0>; + +template<typename T, typename Result> +struct MemberFuncCall0 { + void f(T t) { + Result result = t.f(); + } +}; + +template<typename T> +struct HasMemFunc0 { + T f(); +}; + + +template struct MemberFuncCall0<HasMemFunc0<int&>, const int&>; + +template<typename Result> +struct ThisMemberFuncCall0 { + Result g(); + + void f() { + Result r1 = g(); + Result r2 = this->g(); + } +}; + +template struct ThisMemberFuncCall0<int&>; + +template<typename T> +struct NonDepMemberCall0 { + void foo(HasMemFunc0<int&> x) { + T result = x.f(); // expected-error{{non-const lvalue reference}} + } +}; + +template struct NonDepMemberCall0<int&>; +template struct NonDepMemberCall0<const int&>; +template struct NonDepMemberCall0<float&>; // expected-note{{instantiation}} + + +template<typename T> +struct QualifiedDeclRef0 { + T f() { + return is_pod<X>::value; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'const bool'}} + } +}; + +template struct QualifiedDeclRef0<bool>; +template struct QualifiedDeclRef0<int&>; // expected-note{{instantiation}} |