summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaTemplate/deduction.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-01-04 01:48:55 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-01-04 01:48:55 +0000
commit539e8e37039865a6e46d2e63d192c87104f1e84a (patch)
tree75c8891c45168ba3a528520bdb9661d21757b55a /clang/test/SemaTemplate/deduction.cpp
parente28ab799b22122a08a65d5f041fdbdb3b538958e (diff)
downloadbcm5719-llvm-539e8e37039865a6e46d2e63d192c87104f1e84a.tar.gz
bcm5719-llvm-539e8e37039865a6e46d2e63d192c87104f1e84a.zip
Fix template argument deduction when only some of a parameter pack is a non-deduced context.
When a parameter pack has multiple corresponding arguments, and some subset of them are overloaded functions, it's possible that some subset of the parameters are non-deduced contexts. In such a case, keep deducing from the remainder of the arguments, and resolve the incomplete pack against whatever other deductions we've performed for the pack. GCC, MSVC, and ICC give three different bad behaviors for this case; what we do now (and what we did before) don't exactly match any of them, sadly :( I'm getting a core issue opened to specify more precisely how this should be handled. llvm-svn: 290923
Diffstat (limited to 'clang/test/SemaTemplate/deduction.cpp')
-rw-r--r--clang/test/SemaTemplate/deduction.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp
index 69a3817f735..fdf21bc79a5 100644
--- a/clang/test/SemaTemplate/deduction.cpp
+++ b/clang/test/SemaTemplate/deduction.cpp
@@ -362,3 +362,41 @@ namespace deduction_after_explicit_pack {
g<int, float&, double&>(a, b, c, &c); // ok
}
}
+
+namespace overload_vs_pack {
+ void f(int);
+ void f(float);
+ void g(double);
+
+ template<typename ...T> struct X {};
+ template<typename ...T> void x(T...);
+
+ template<typename ...T> struct Y { typedef int type(typename T::error...); };
+ template<> struct Y<int, float, double> { typedef int type; };
+
+ template<typename ...T> typename Y<T...>::type g1(X<T...>, void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
+ template<typename ...T> typename Y<T...>::type g2(void(*)(T...), void (*...fns)(T)); // expected-note {{deduced conflicting types for parameter 'T' (<int, float> vs. <(no value), double>)}}
+
+ template<typename T> int &h1(decltype(g1(X<int, float, T>(), f, f, g)) *p);
+ template<typename T> float &h1(...);
+
+ template<typename T> int &h2(decltype(g2(x<int, float, T>, f, f, g)) *p);
+ template<typename T> float &h2(...);
+
+ int n1 = g1(X<int, float>(), f, g); // expected-error {{no matching function}}
+ int n2 = g2(x<int, float>, f, g); // expected-error {{no matching function}}
+ int n3 = g1(X<int, float, double, char>(), f);
+ int n4 = g2(x<int, float, double, long>, f);
+
+ int &a1 = h1<double>(0); // ok, skip deduction for 'f's, deduce matching value from 'g'
+ int &a2 = h2<double>(0);
+
+ float &b1 = h1<float>(0); // deduce mismatching value from 'g', so we do not trigger instantiation of Y
+ float &b2 = h2<float>(0);
+
+ template<typename ...T> int partial_deduction(void (*...f)(T)); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
+ int pd1 = partial_deduction(f, g); // expected-error {{no matching function}}
+
+ template<typename ...T> int partial_deduction_2(void (*...f)(T), ...); // expected-note {{deduced incomplete pack <(no value), double> for template parameter 'T'}}
+ int pd2 = partial_deduction_2(f, g); // expected-error {{no matching function}}
+}
OpenPOWER on IntegriCloud