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.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 ++++++++++++++++++ 7 files changed, 491 insertions(+) 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 (limited to 'clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call') 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); + } +} -- cgit v1.2.3