From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- .../temp/temp.fct.spec/temp.arg.explicit/p1.cpp | 12 ++ .../temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp | 27 ++++ .../temp.arg.explicit/p3-nodeduct.cpp | 36 +++++ .../temp/temp.fct.spec/temp.arg.explicit/p3.cpp | 65 +++++++++ .../temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp | 68 ++++++++++ .../CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp | 41 ++++++ .../test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp | 26 ++++ .../temp/temp.fct.spec/temp.deduct/sfinae-1.cpp | 42 ++++++ .../temp.deduct/temp.deduct.call/basic.cpp | 30 +++++ .../temp.deduct/temp.deduct.call/p1-0x.cpp | 88 ++++++++++++ .../temp.deduct/temp.deduct.call/p2.cpp | 31 +++++ .../temp.deduct/temp.deduct.call/p3-0x.cpp | 46 +++++++ .../temp.deduct/temp.deduct.call/p3.cpp | 148 +++++++++++++++++++++ .../temp.deduct/temp.deduct.call/p4.cpp | 20 +++ .../temp.deduct/temp.deduct.call/p6.cpp | 128 ++++++++++++++++++ .../temp.deduct/temp.deduct.conv/p2.cpp | 36 +++++ .../temp.deduct/temp.deduct.conv/p3.cpp | 30 +++++ .../temp.deduct/temp.deduct.conv/p4.cpp | 44 ++++++ .../temp.deduct/temp.deduct.funcaddr/p1.cpp | 22 +++ .../temp.deduct/temp.deduct.partial/p11.cpp | 47 +++++++ .../temp.deduct/temp.deduct.partial/p12.cpp | 27 ++++ .../temp.deduct/temp.deduct.partial/p9-0x.cpp | 10 ++ .../temp.deduct/temp.deduct.type/p10-0x.cpp | 4 + .../temp.deduct/temp.deduct.type/p17.cpp | 31 +++++ .../temp.deduct/temp.deduct.type/p2-0x.cpp | 23 ++++ .../temp.deduct/temp.deduct.type/p21.cpp | 31 +++++ .../temp.deduct/temp.deduct.type/p22.cpp | 14 ++ .../temp.deduct/temp.deduct.type/p5-0x.cpp | 22 +++ .../temp.deduct/temp.deduct.type/p8-0x.cpp | 47 +++++++ .../temp.deduct/temp.deduct.type/p9-0x.cpp | 55 ++++++++ 30 files changed, 1251 insertions(+) create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp create mode 100644 clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp (limited to 'clang/test/CXX/temp/temp.fct.spec') diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp new file mode 100644 index 0000000..0aef6ad --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only %s + +template struct A { }; + +template T make(); +template T make2(const T&); + +void test_make() { + int& ir0 = make(); + A a0 = make< A >(); + A a1 = make2< A >(A()); +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp new file mode 100644 index 0000000..4d29b74 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +namespace ParameterPacksWithFunctions { + template struct count; + + template + struct count { + static const unsigned value = 1 + count::value; + }; + + template<> + struct count<> { + static const unsigned value = 0; + }; + + template struct unsigned_c { }; + + template + unsigned_c::value> f(); + + void test_f() { + unsigned_c<0> uc0a = f(); // okay, deduced to an empty pack + unsigned_c<0> uc0b = f<>(); + unsigned_c<1> uc1 = f(); + unsigned_c<2> uc2 = f(); + } +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp new file mode 100644 index 0000000..de3b44f --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR5811 +template void Call(F f) { f(1); } +template void f(T); +void a() { Call(f); } + +// Check the conversion of a template-id to a pointer +template struct Constant { }; +Constant > constant0; + +template void constant_func(); +void test_constant_func() { + constant_func >(); +} + + +// Check typeof() on a template-id referring to a single function +template +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + static const bool value = true; +}; + +int typeof0[is_same<__typeof__(f), void (int)>::value? 1 : -1]; +int typeof1[is_same<__typeof__(&f), void (*)(int)>::value? 1 : -1]; + +template void g(T); // expected-note{{possible target for call}} +template void g(T, T); // expected-note{{possible target for call}} + +int typeof2[is_same<__typeof__(g), void (int)>::value? 1 : -1]; // \ + // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp new file mode 100644 index 0000000..5556f35 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template X f(Y,Z); // expected-note {{candidate template ignored: couldn't infer template argument 'X'}} + +void g() { + f("aa",3.0); // expected-warning{{conversion from string literal to 'char *' is deprecated}} + f("aa",3.0); // Z is deduced to be double \ + // expected-warning{{conversion from string literal to 'char *' is deprecated}} + f("aa",3.0); // Y is deduced to be char*, and + // Z is deduced to be double + f("aa",3.0); // expected-error{{no matching}} +} + +// PR5910 +namespace PR5910 { + template + void Func() {} + + template + void Foo(R (*fp)()); + + void Test() { + Foo(Func); + } +} + +// PR5949 +namespace PR5949 { + struct Bar; + + template + void quuz(const Container &cont) { + } + + template + int Foo(Bar *b, void (*Baz)(const T &t), T * = 0) { + return 0; + } + + template + int Quux(Bar *b, T * = 0) + { + return Foo(b, quuz); + } +} + +// PR7641 +namespace PR7641 { + namespace N2 + { + template + int f0(int); + } + namespace N + { + using N2::f0; + } + + template + int + f1(R(a)(B1)); + + void f2() + { f1(N::f0); } +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp new file mode 100644 index 0000000..81addfe --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// Metafunction to extract the Nth type from a set of types. +template struct get_nth_type; + +template +struct get_nth_type : get_nth_type { }; + +template +struct get_nth_type<0, Head, Tail...> { + typedef Head type; +}; + +// Placeholder type when get_nth_type fails. +struct no_type {}; + +template +struct get_nth_type { + typedef no_type type; +}; + +template +typename get_nth_type<0, Args...>::type first_arg(Args...); + +template +typename get_nth_type<1, Args...>::type second_arg(Args...); + +// Test explicit specification of function template arguments. +void test_explicit_spec_simple() { + int *ip1 = first_arg(0); + int *ip2 = first_arg(0, 0); + float *fp1 = first_arg(0, 0, 0); +} + +// Template argument deduction can extend the sequence of template +// arguments corresponding to a template parameter pack, even when the +// sequence contains explicitly specified template arguments. +void test_explicit_spec_extension(double *dp) { + int *ip1 = first_arg(0, 0); + int *ip2 = first_arg(0, 0, 0, 0); + float *fp1 = first_arg(0, 0, 0); + int *i1 = second_arg(0, (int*)0, 0); + double *dp1 = first_arg<>(dp); +} + +template +struct tuple { }; + +template +void accept_tuple(tuple); + +void test_explicit_spec_extension_targs(tuple t3) { + accept_tuple(t3); + accept_tuple(t3); + accept_tuple(t3); + accept_tuple(t3); +} + +template +void accept_function_ptr(R(*)(ParmTypes...)); + +void test_explicit_spec_extension_funcparms(int (*f3)(int, float, double)) { + accept_function_ptr(f3); + accept_function_ptr(f3); + accept_function_ptr(f3); + accept_function_ptr(f3); + accept_function_ptr(f3); +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp new file mode 100644 index 0000000..c14b063 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +#if !__has_feature(cxx_access_control_sfinae) +# error No support for access control as part of SFINAE? +#endif + +typedef char yes_type; +typedef char (&no_type)[2]; + +template struct unsigned_c { }; + +template +class has_copy_constructor { + static T t; + + template static yes_type check(unsigned_c * = 0); + template static no_type check(...); + +public: + static const bool value = (sizeof(check(0)) == sizeof(yes_type)); +}; + +struct HasCopy { }; + +struct HasNonConstCopy { + HasNonConstCopy(HasNonConstCopy&); +}; + +struct HasDeletedCopy { + HasDeletedCopy(const HasDeletedCopy&) = delete; +}; + +struct HasPrivateCopy { +private: + HasPrivateCopy(const HasPrivateCopy&); +}; + +int check0[has_copy_constructor::value? 1 : -1]; +int check1[has_copy_constructor::value? 1 : -1]; +int check2[has_copy_constructor::value? -1 : 1]; +int check3[has_copy_constructor::value? -1 : 1]; diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp new file mode 100644 index 0000000..c27261c --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template int f(int); // expected-note 2{{candidate}} +template int f(int); // expected-note 2{{candidate}} +int i1 = f<1>(0); // expected-error{{ambiguous}} +int i2 = f<1000>(0); // expected-error{{ambiguous}} + +namespace PR6707 { + template + struct X { }; + + template + void f(X); + + void g(X x) { + f(x); + } + + static const unsigned char ten = 10; + template + void f2(X, X); + + void g2() { + f2(X(), X()); + } +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp new file mode 100644 index 0000000..6481485 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -verify %s + +typedef char one_byte; +struct two_bytes { char data[2]; }; + +template one_byte __is_class_check(int T::*); +template two_bytes __is_class_check(...); + +template struct is_class { + static const bool value = sizeof(__is_class_check(0)) == 1; +}; + +struct X { }; + +int array0[is_class::value? 1 : -1]; +int array1[is_class::value? -1 : 1]; +int array2[is_class::value? -1 : 1]; + +namespace instantiation_order1 { + template + struct it_is_a_trap { + typedef typename T::trap type; + }; + + template + struct enable_if { + typedef T type; + }; + + template + struct enable_if { }; + + template + typename enable_if::type + f(const T&, typename it_is_a_trap::type* = 0); + + void f(...); + + void test_f() { + f('a'); + } +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp new file mode 100644 index 0000000..90d2949 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template struct A { }; + +template A f0(T*); + +void test_f0(int *ip, float const *cfp) { + A a0 = f0(ip); + A a1 = f0(cfp); +} + +template void f1(T*, int); + +void test_f1(int *ip, float fv) { + f1(ip, fv); +} + +// TODO: this diagnostic can and should improve +template void f2(T*, T*); // expected-note {{candidate template ignored: failed template argument deduction}} \ +// expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'float')}} + +struct ConvToIntPtr { + operator int*() const; +}; + +void test_f2(int *ip, float *fp) { + f2(ip, ConvToIntPtr()); // expected-error{{no matching function}} + f2(ip, ip); // okay + f2(ip, fp); // expected-error{{no matching function}} +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp new file mode 100644 index 0000000..8b192fa --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp @@ -0,0 +1,88 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// Metafunction to extract the Nth type from a set of types. +template struct get_nth_type; + +template +struct get_nth_type : get_nth_type { }; + +template +struct get_nth_type<0, Head, Tail...> { + typedef Head type; +}; + +// Placeholder type when get_nth_type fails. +struct no_type {}; + +template +struct get_nth_type { + typedef no_type type; +}; + +template struct pair { }; +template pair make_pair(T, U); + +// For a function parameter pack that occurs at the end of the +// parameter-declaration-list, the type A of each remaining argument +// of the call is compared with the type P of the declarator-id of the +// function parameter pack. +template +typename get_nth_type<0, Args...>::type first_arg(Args...); + +template +typename get_nth_type<1, Args...>::type second_arg(Args...); + +void test_simple_deduction(int *ip, float *fp, double *dp) { + int *ip1 = first_arg(ip); + int *ip2 = first_arg(ip, fp); + int *ip3 = first_arg(ip, fp, dp); + no_type nt1 = first_arg(); +} + +template +typename get_nth_type<0, Args...>::type first_arg_ref(Args&...); + +template +typename get_nth_type<1, Args...>::type second_arg_ref(Args&...); + +void test_simple_ref_deduction(int *ip, float *fp, double *dp) { + int *ip1 = first_arg_ref(ip); + int *ip2 = first_arg_ref(ip, fp); + int *ip3 = first_arg_ref(ip, fp, dp); + no_type nt1 = first_arg_ref(); +} + + +template +typename get_nth_type<0, Args1...>::type first_arg_pair(pair...); // expected-note{{candidate template ignored: failed template argument deduction}} + +template +typename get_nth_type<1, Args1...>::type second_arg_pair(pair...); + +void test_pair_deduction(int *ip, float *fp, double *dp) { + int *ip1 = first_arg_pair(make_pair(ip, 17)); + int *ip2 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17)); + int *ip3 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17), + make_pair(dp, 17)); + float *fp1 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17)); + float *fp2 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17), + make_pair(dp, 17)); + no_type nt1 = first_arg_pair(); + no_type nt2 = second_arg_pair(); + no_type nt3 = second_arg_pair(make_pair(ip, 17)); + + + first_arg_pair(make_pair(ip, 17), 16); // expected-error{{no matching function for call to 'first_arg_pair'}} +} + +// For a function parameter pack that does not occur at the end of the +// parameter-declaration-list, the type of the parameter pack is a +// non-deduced context. +template struct tuple { }; + +template +void pack_not_at_end(tuple, Types... values, int); + +void test_pack_not_at_end(tuple t2) { + pack_not_at_end(t2, 0, 0, 0); +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp new file mode 100644 index 0000000..c165c45 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +template struct A { }; + +// bullet 1 +template A f0(T* ptr); + +void test_f0_bullet1() { + int arr0[6]; + A a0 = f0(arr0); + const int arr1[] = { 1, 2, 3, 4, 5 }; + A a1 = f0(arr1); +} + +// bullet 2 +int g0(int, int); +float g1(float); + +void test_f0_bullet2() { + A a0 = f0(g0); + A a1 = f0(g1); +} + +// bullet 3 +struct X { }; +const X get_X(); + +template A f1(T); + +void test_f1_bullet3() { + A a0 = f1(get_X()); +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp new file mode 100644 index 0000000..e470dd0 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + + +// If P is an rvalue reference to a cv-unqualified template parameter +// and the argument is an lvalue, the type "lvalue reference to A" is +// used in place of A for type deduction. +template struct X { }; + +template X f0(T&&); + +struct Y { }; + +template T prvalue(); +template T&& xvalue(); +template T& lvalue(); + +void test_f0() { + X xi0 = f0(prvalue()); + X xi1 = f0(xvalue()); + X xi2 = f0(lvalue()); + X xy0 = f0(prvalue()); + X xy1 = f0(xvalue()); + X xy2 = f0(lvalue()); +} + +template X f1(const T&&); // expected-note{{candidate function [with T = int] not viable: no known conversion from 'int' to 'const int &&' for 1st argument}} \ +// expected-note{{candidate function [with T = Y] not viable: no known conversion from 'Y' to 'const Y &&' for 1st argument}} + +void test_f1() { + X xi0 = f1(prvalue()); + X xi1 = f1(xvalue()); + f1(lvalue()); // expected-error{{no matching function for call to 'f1'}} + X xy0 = f1(prvalue()); + X xy1 = f1(xvalue()); + f1(lvalue()); // expected-error{{no matching function for call to 'f1'}} +} + +namespace std_example { + template int f(T&&); + template int g(const T&&); // expected-note{{candidate function [with T = int] not viable: no known conversion from 'int' to 'const int &&' for 1st argument}} + + int i; + int n1 = f(i); + int n2 = f(0); + int n3 = g(i); // expected-error{{no matching function for call to 'g'}} +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp new file mode 100644 index 0000000..295f080 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp @@ -0,0 +1,148 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template struct A { }; + +// Top-level cv-qualifiers of P's type are ignored for type deduction. +template A f0(const T); + +void test_f0(int i, const int ci) { + A a0 = f0(i); + A a1 = f0(ci); +} + +// If P is a reference type, the type referred to by P is used for type +// deduction. +template A f1(T&); + +void test_f1(int i, const int ci, volatile int vi) { + A a0 = f1(i); + A a1 = f1(ci); + A a2 = f1(vi); +} + +template struct B { }; +template B g0(T (&array)[N]); +template B g0b(const T (&array)[N]); + +void test_g0() { + int array0[5]; + B b0 = g0(array0); + const int array1[] = { 1, 2, 3}; + B b1 = g0(array1); + B b2 = g0b(array1); +} + +template B g1(const A&); + +void test_g1(A af) { + B b0 = g1(af); + B b1 = g1(A()); +} + +// - If the original P is a reference type, the deduced A (i.e., the type +// referred to by the reference) can be more cv-qualified than the +// transformed A. +template A f2(const T&); + +void test_f2(int i, const int ci, volatile int vi) { + A a0 = f2(i); + A a1 = f2(ci); + A a2 = f2(vi); +} + +// PR5913 +template +void Foo(const T (&a)[N]) { + T x; + x = 0; +} + +const int a[1] = { 0 }; + +void Test() { + Foo(a); +} + +// - The transformed A can be another pointer or pointer to member type that +// can be converted to the deduced A via a qualification conversion (4.4). +template A f3(T * * const * const); + +void test_f3(int ***ip, volatile int ***vip) { + A a0 = f3(ip); + A a1 = f3(vip); +} + +// Also accept conversions for pointer types which require removing +// [[noreturn]]. +namespace noreturn_stripping { + template + void f(R (*function)()); + + void g() __attribute__ ((__noreturn__)); + void h(); + void test() { + f(g); + f(h); + } +} + +// - If P is a class, and P has the form template-id, then A can be a +// derived class of the deduced A. Likewise, if P is a pointer to a class +// of the form template-id, A can be a pointer to a derived class pointed +// to by the deduced A. +template struct C { }; + +struct D : public C { }; +struct E : public D { }; +struct F : A { }; +struct G : A, C { }; + +template + C *f4a(const C&); +template + C *f4b(C); +template + C *f4c(C*); +int *f4c(...); + +void test_f4(D d, E e, F f, G g) { + C *ci1a = f4a(d); + C *ci2a = f4a(e); + C *ci1b = f4b(d); + C *ci2b = f4b(e); + C *ci1c = f4c(&d); + C *ci2c = f4c(&e); + C *ci3c = f4c(&g); + int *ip1 = f4c(&f); +} + +// PR8462 +namespace N { + struct T0; + struct T1; + + template struct B {}; + + struct J : B {}; + struct K : B {}; + + struct D : J, K {}; + + template void F(B); + + void test() + { + D d; + N::F(d); // Fails + N::F(d); // OK + } +} + +namespace PR9233 { + template void f(const T **q); // expected-note{{candidate template ignored: substitution failure [with T = int]}} + + void g(int **p) { + f(p); // expected-error{{no matching function for call to 'f'}} + } + +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp new file mode 100644 index 0000000..83b5f23 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace PR8598 { + template struct identity { typedef T type; }; + + template + void f(T C::*, typename identity::type*){} + + struct X { void f() {}; }; + + void g() { (f)(&X::f, 0); } +} + +namespace PR12132 { + template void fun(const int* const S::* member) {} + struct A { int* x; }; + void foo() { + fun(&A::x); + } +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp new file mode 100644 index 0000000..8b18189 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp @@ -0,0 +1,128 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace test0 { + template void apply(T x, void (*f)(T)) { f(x); } // expected-note 2 {{candidate template ignored: deduced conflicting types for parameter 'T'}}\ + // expected-note {{no overload of 'temp2' matching 'void (*)(int)'}} + + template void temp(A); + void test0() { + // okay: deduce T=int from first argument, A=int during overload + apply(0, &temp); + apply(0, &temp<>); + + // okay: deduce T=int from first and second arguments + apply(0, &temp); + + // deduction failure: T=int from first, T=long from second + apply(0, &temp); // expected-error {{no matching function for call to 'apply'}} + } + + void over(int); + int over(long); + + void test1() { + // okay: deductions match + apply(0, &over); + + // deduction failure: deduced T=long from first argument, T=int from second + apply(0L, &over); // expected-error {{no matching function for call to 'apply'}} + } + + void over(short); + + void test2() { + // deduce T=int from first arg, second arg is undeduced context, + // pick correct overload of 'over' during overload resolution for 'apply' + apply(0, &over); + } + + template B temp2(A); + void test3() { + // deduce T=int from first arg, A=int B=void during overload resolution + apply(0, &temp2); + apply(0, &temp2<>); + apply(0, &temp2); + + // overload failure + apply(0, &temp2); // expected-error {{no matching function for call to 'apply'}} + } +} + +namespace test1 { + template void invoke(void (*f)(T)) { f(T()); } // expected-note 6 {{couldn't infer template argument}} \ + // expected-note {{candidate template ignored: couldn't infer template argument 'T'}} + + template void temp(T); + void test0() { + // deduction failure: overload has template => undeduced context + invoke(&temp); // expected-error {{no matching function for call to 'invoke'}} + invoke(&temp<>); // expected-error {{no matching function for call to 'invoke'}} + + // okay: full template-id + invoke(&temp); + } + + void over(int); + int over(long); + + void test1() { + // okay: only one overload matches + invoke(&over); + } + + void over(short); + + void test2() { + // deduction failure: overload has multiple matches => undeduced context + invoke(&over); // expected-error {{no matching function for call to 'invoke'}} + } + + template B temp2(A); + void test3() { + // deduction failure: overload has template => undeduced context + // (even though partial application temp2 could in theory + // let us infer T=int) + invoke(&temp2); // expected-error {{no matching function for call to 'invoke'}} + invoke(&temp2<>); // expected-error {{no matching function for call to 'invoke'}} + invoke(&temp2); // expected-error {{no matching function for call to 'invoke'}} + + // okay: full template-id + invoke(&temp2); + + // overload failure + invoke(&temp2); // expected-error {{no matching function for call to 'invoke'}} + } +} + +namespace rdar8360106 { + template void f0(R (*)(T), T); + template void f1(R (&)(T) , T); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}} + template void f2(R (* const&)(T), T); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}} + + int g(int); + int g(int, int); + + void h() { + f0(g, 1); + f0(&g, 1); + f1(g, 1); + f1(&g, 1); // expected-error{{no matching function for call to 'f1'}} + f2(g, 1); // expected-error{{no matching function for call to 'f2'}} + f2(&g, 1); + } +} + +namespace PR11713 { + template + int f(int, int, int); + + template + float f(float, float); + + template + R& g(R (*)(B1, B2), A1, A2); + + void h() { + float &fr = g(f, 1, 2); + } +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp new file mode 100644 index 0000000..5a9ea08 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// FIXME: [temp.deduct.conv]p2 bullets 1 and 2 can't actually happen without +// references? +// struct ConvertibleToArray { +// // template +// // operator T(()[]) const; + +// private: +// typedef int array[17]; + +// operator array() const; +// }; + +// void test_array(ConvertibleToArray cta) { +// int *ip = cta; +// ip = cta; +// const float *cfp = cta; +// } + +// bullet 2 +// struct ConvertibleToFunction { +// template +// operator T(A1, A2) const () { }; +// }; + +// bullet 3 +struct ConvertibleToCVQuals { + template + operator T* const() const; +}; + +void test_cvqual_conv(ConvertibleToCVQuals ctcv) { + int *ip = ctcv; + const int *icp = ctcv; +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp new file mode 100644 index 0000000..e23e98a --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +struct AnyPtr { + template + operator T*() const; +}; + +// If A is a cv-qualified type, the top level cv-qualifiers of A's type +// are ignored for type deduction. +void test_cvquals(AnyPtr ap) { + int* const ip = ap; + const float * const volatile fp = ap; +} + +// If A is a reference type, the type referred to by A is used for +// type deduction. +void test_ref_arg(AnyPtr ap) { + const int* const &ip = ap; + double * const &dp = ap; +} + +struct AnyRef { + template + operator T&() const; +}; + +void test_ref_param(AnyRef ar) { + int &ir = ar; + const float &fr = ar; + int i = ar; +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp new file mode 100644 index 0000000..4dca820 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -fsyntax-only %s + +struct AnyT { + template + operator T(); +}; + +void test_cvqual_ref(AnyT any) { + const int &cir = any; +} + +struct AnyThreeLevelPtr { + template + operator T***() const + { + T x = 0; + // FIXME: looks like we get this wrong, too! + // x = 0; // will fail if T is deduced to a const type + // (EDG and GCC get this wrong) + return 0; + } +}; + +struct X { }; + +void test_deduce_with_qual(AnyThreeLevelPtr a3) { + int * const * const * const ip = a3; +} + +struct AnyPtrMem { + template + operator T Class::*() const + { + T x = 0; + // FIXME: looks like we get this wrong, too! + // x = 0; // will fail if T is deduced to a const type. + // (EDG and GCC get this wrong) + return 0; + } +}; + +void test_deduce_ptrmem_with_qual(AnyPtrMem apm) { + const float X::* pm = apm; +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp new file mode 100644 index 0000000..99a265a --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fsyntax-only %s + +template + T f0(T, int); + +void test_f0() { + int (*f0a)(int, int) = f0; + int (*f0b)(int, int) = &f0; + float (*f0c)(float, int) = &f0; +} + +template T f1(T, int); +template T f1(T); + +void test_f1() { + float (*f1a)(float, int) = f1; + float (*f1b)(float, int) = &f1; + float (*f1c)(float) = f1; + float (*f1d)(float) = (f1); + float (*f1e)(float) = &f1; + float (*f1f)(float) = (&f1); +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp new file mode 100644 index 0000000..01155e1 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template T* f(int); // #1 +template T& f(U); // #2 + +void g() { + int *ip = f(1); // calls #1 +} + +template +struct identity { + typedef T type; +}; + +template + T* f2(int, typename identity::type = 0); +template + T& f2(U, typename identity::type = 0); + +void g2() { + int* ip = f2(1); +} + +template struct A { }; + +template inline int *f3( U, A* p = 0 ); // #1 expected-note{{candidate function [with T = int, U = int]}} +template< class U> inline float *f3( U, A* p = 0 ); // #2 expected-note{{candidate function [with U = int]}} + +void g3() { + float *fp = f3( 42, (A*)0 ); // Ok, picks #2. + f3( 42 ); // expected-error{{call to 'f3' is ambiguous}} + +} + +namespace PR9006 { + struct X { + template + int &f(char const* name, Get fget, char const* docstr = 0); + + template + float &f(char const* name, Get fget, Set fset, char const* docstr = 0); + }; + + void test(X x) { + int &ir = x.f("blah", 0, "blah"); + } +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp new file mode 100644 index 0000000..b965300 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// Note: Partial ordering of function templates containing template +// parameter packs is independent of the number of deduced arguments +// for those template parameter packs. +template struct Tuple { }; +template int &g(Tuple); // #1 +template float &g(Tuple); // #2 +template double &g(Tuple); // #3 + +void test_g() { + int &ir1 = g(Tuple<>()); + float &fr1 = g(Tuple()); + double &dr1 = g(Tuple()); + double &dr2 = g(Tuple()); +} + +template int &h(int (*)(Types ...)); // #1 +template float &h(int (*)(T1, Types ...)); // #2 +template double &h(int (*)(T1, Types& ...)); // #3 + +void test_h() { + int &ir1 = h((int(*)())0); + float &fr1 = h((int(*)(int, float))0); + double &dr1 = h((int(*)(int, float&))0); + double &dr2 = h((int(*)(int))0); +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp new file mode 100644 index 0000000..f204caf --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +template int &f0(T&); +template float &f0(T&&); + +// Core issue 1164 +void test_f0(int i) { + int &ir0 = f0(i); + float &fr0 = f0(5); +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp new file mode 100644 index 0000000..8183061 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +template void f(T&&); +template<> void f(int&) { } +void (*fp)(int&) = &f; diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp new file mode 100644 index 0000000..bf5f962 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template class A { }; +template void f(A); // expected-note{{candidate template ignored: substitution failure}} + +void k1() { + A<1> a; + f(a); // expected-error{{no matching function for call}} + f<1>(a); +} +template class B { }; +template void g(B); +void k2() { + B<1> b; + g(b); // OK: cv-qualifiers are ignored on template parameter types +} + +template void h(int (&)[s]); // expected-note{{candidate function template not viable: requires 1 argument, but 2 were provided}} +void k3() { + int array[5]; + h(array); + h<5>(array); +} + +template void h(int (&)[s], A); // expected-note{{candidate template ignored: substitution failure}} +void k4() { + A<5> a; + int array[5]; + h(array, a); // expected-error{{no matching function for call}} + h<5>(array, a); +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp new file mode 100644 index 0000000..5b031c2 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// If type deduction cannot be done for any P/A pair, or if for any +// pair the deduction leads to more than one possible set of deduced +// values, or if different pairs yield different deduced values, or if +// any template argument remains neither deduced nor explicitly +// specified, template argument deduction fails. + +template struct tuple; + +template +struct same_tuple { + static const bool value = false; +}; + +template +struct same_tuple, tuple > { + static const bool value = true; +}; + +int same_tuple_check1[same_tuple, tuple>::value? -1 : 1]; +int same_tuple_check2[same_tuple, tuple>::value? 1 : -1]; + diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp new file mode 100644 index 0000000..4e98a6d --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// Note: Template argument deduction involving parameter packs +// (14.5.3) can deduce zero or more arguments for each parameter pack. + +template struct X { + static const unsigned value = 0; +}; + +template struct X { + static const unsigned value = 1; +}; + +template struct Y { + static const unsigned value = 0; +}; + +template struct Y { + static const unsigned value = 1; +}; + +template int f(void (*)(Types ...)); +void g(int, float); + +int check0[X::value == 0? 1 : -1]; // uses primary template +int check1[X::value == 1? 1 : -1]; // uses partial specialization +int check2[X::value == 0? 1 : -1]; // uses primary template +int check3[Y<>::value == 0? 1 : -1]; // uses primary template +int check4[Y::value == 1? 1 : -1]; // uses partial specialization +int check5[Y::value == 0? 1 : -1]; // uses primary template +int fv = f(g); // okay diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp new file mode 100644 index 0000000..fcc6cf7 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// If the original function parameter associated with A is a function +// parameter pack and the function parameter associated with P is not +// a function parameter pack, then template argument deduction fails. +template int& f(Args ... args); +template float& f(T1 a1, Args ... args); +template double& f(T1 a1, T2 a2); + +void test_f() { + int &ir1 = f(); + float &fr1 = f(1, 2, 3); + double &dr1 = f(1, 2); +} diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp new file mode 100644 index 0000000..c819d97 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// FIXME: More bullets to go! + +template +struct has_nondeduced_pack_test { + static const bool value = false; +}; + +template +struct has_nondeduced_pack_test { + static const bool value = true; +}; + +// - A function parameter pack that does not occur at the end of the +// parameter-declaration-clause. +int check_nondeduced_pack_test0[ + has_nondeduced_pack_test::value? 1 : -1]; + + diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp new file mode 100644 index 0000000..a6b1172 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// Deductions specific to C++0x. + +template +struct member_pointer_kind { + static const unsigned value = 0; +}; + +template +struct member_pointer_kind { + static const unsigned value = 1; +}; + +template +struct member_pointer_kind { + static const unsigned value = 2; +}; + +template +struct member_pointer_kind { + static const unsigned value = 3; +}; + +template +struct member_pointer_kind { + static const unsigned value = 4; +}; + +template +struct member_pointer_kind { + static const unsigned value = 5; +}; + +template +struct member_pointer_kind { + static const unsigned value = 6; +}; + +struct X { }; + +static_assert(member_pointer_kind::value == 1, ""); +static_assert(member_pointer_kind::value == 2, ""); +static_assert(member_pointer_kind::value == 3, ""); +static_assert(member_pointer_kind::value == 4, ""); +static_assert(member_pointer_kind::value == 5, ""); +static_assert(member_pointer_kind::value == 6, ""); diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp new file mode 100644 index 0000000..7774b5c --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +template struct tuple; +template struct unsigned_c; + +template +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + static const bool value = true; +}; + +namespace PackExpansionNotAtEnd { + template + struct tuple_same_with_int { + static const bool value = false; + }; + + template + struct tuple_same_with_int, tuple> { + static const bool value = true; + }; + + int tuple_same_with_int_1[tuple_same_with_int, + tuple + >::value? 1 : -1]; + + template struct UselessPartialSpec; + + template // expected-note{{non-deducible template parameter 'Tail'}} + struct UselessPartialSpec; // expected-warning{{class template partial specialization contains template parameters that can not be deduced; this partial specialization will never be used}} +} + +namespace DeduceNonTypeTemplateArgsInArray { + template + struct split_arrays; + + template + struct split_arrays { + typedef tuple element_types; + + // FIXME: Would like to have unsigned_tuple here. + typedef tuple...> bounds_types; + }; + + int check1[is_same::element_types, + tuple>::value? 1 : -1]; + int check2[is_same::bounds_types, + tuple, unsigned_c<2>, unsigned_c<3>> + >::value? 1 : -1]; +} -- cgit v1.2.3