Template argument deduction for std::initializer_list arguments from initializer lists.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148352 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 87e7e84..a08a048 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -32,6 +32,11 @@
   };
 }
 
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
 struct one { char c[1]; };
 struct two { char c[2]; };
 
@@ -87,3 +92,20 @@
     // But here, user-defined is worst in both cases.
     ov2({1, 2, D()}); // expected-error {{ambiguous}}
 }
+
+template <typename T>
+T deduce(std::initializer_list<T>); // expected-note {{conflicting types for parameter 'T' ('int' vs. 'double')}}
+template <typename T>
+T deduce_ref(const std::initializer_list<T>&); // expected-note {{conflicting types for parameter 'T' ('int' vs. 'double')}}
+
+void argument_deduction() {
+  static_assert(same_type<decltype(deduce({1, 2, 3})), int>::value, "bad deduction");
+  static_assert(same_type<decltype(deduce({1.0, 2.0, 3.0})), double>::value, "bad deduction");
+
+  deduce({1, 2.0}); // expected-error {{no matching function}}
+
+  static_assert(same_type<decltype(deduce_ref({1, 2, 3})), int>::value, "bad deduction");
+  static_assert(same_type<decltype(deduce_ref({1.0, 2.0, 3.0})), double>::value, "bad deduction");
+
+  deduce_ref({1, 2.0}); // expected-error {{no matching function}}
+}