Fix handling of explicit function template arguments with TTPs.
authorJason Merrill <jason@redhat.com>
Wed, 21 Dec 2016 19:38:44 +0000 (14:38 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 21 Dec 2016 19:38:44 +0000 (14:38 -0500)
gcc/cp/
* pt.c (coerce_template_parms): Consider variadic_args_p before
complaining about too many template arguments.
libstdc++-v3/
* testsuite/util/testsuite_tr1.h (test_property): Don't define both
variadic and non-variadic overloads.

From-SVN: r243869

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/variadic-ttp3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/variadic-ttp3a.C [new file with mode: 0644]
libstdc++-v3/ChangeLog
libstdc++-v3/testsuite/util/testsuite_tr1.h

index 7faac155e3408dc100275134575c8639bdc1c61b..05d6dba39c32cddf4a9cf655f4bad7b57a8d9d9b 100644 (file)
@@ -1,5 +1,8 @@
 2016-12-21  Jason Merrill  <jason@redhat.com>
 
+       * pt.c (coerce_template_parms): Consider variadic_args_p before
+       complaining about too many template arguments.
+
        * pt.c (process_partial_specialization): Use
        get_partial_spec_bindings to check that the partial specialization
        is more specialized than the primary template.
index 8abbcfb6f43f135b637aeb59aab6e53116c86c64..f839c5384879fdc7c0a7de3085e134f0498518f5 100644 (file)
@@ -7658,7 +7658,7 @@ coerce_template_parms (tree parms,
   variadic_args_p = pack_expansion_args_count (inner_args);
 
   nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
-  if ((nargs > nparms && !variadic_p)
+  if ((nargs - variadic_args_p > nparms && !variadic_p)
       || (nargs < nparms - variadic_p
          && require_all_args
          && !variadic_args_p
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ttp3.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp3.C
new file mode 100644 (file)
index 0000000..b1bd7a4
--- /dev/null
@@ -0,0 +1,23 @@
+// Test that passing a non-variadic template to a variadic TTP works
+// with explicit template arguments in a function call..
+// { dg-do compile { target c++11 } }
+
+template<template<typename> class Property, typename Type>
+bool test_property(typename Property<Type>::value_type value);
+
+template<template<typename...> class Property,
+        typename Type1, typename... Types>
+bool test_property(typename Property<Type1, Types...>::value_type value);
+
+template <class T>
+struct X
+{
+  using type = X;
+  using value_type = int;
+  static const value_type value = 42;
+};
+
+int main()
+{
+  test_property<X,int>(42);    // { dg-error "ambiguous" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ttp3a.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ttp3a.C
new file mode 100644 (file)
index 0000000..b3599b6
--- /dev/null
@@ -0,0 +1,20 @@
+// Test that passing a non-variadic template to a variadic TTP works
+// with explicit template arguments in a function call..
+// { dg-do compile { target c++11 } }
+
+template<template<typename...> class Property,
+        typename Type1, typename... Types>
+bool test_property(typename Property<Type1, Types...>::value_type value);
+
+template <class T>
+struct X
+{
+  using type = X;
+  using value_type = int;
+  static const value_type value = 42;
+};
+
+int main()
+{
+  test_property<X,int>(42);
+}
index 02297e0f2bb03c7e6239ac8d504874a0edc9bdf2..6263652977daa2c9428a2c17cc56e8a29297c042 100644 (file)
@@ -1,3 +1,8 @@
+2016-12-16  Jason Merrill  <jason@redhat.com>
+
+       * testsuite/util/testsuite_tr1.h (test_property): Don't define both
+       variadic and non-variadic overloads.
+
 2016-12-21  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/71444
index c6a4986b983dc3b2855fd2142e232bf506dbf1e0..908a788a93ef81ebe86b8cdd190c8466a0e5a4b2 100644 (file)
@@ -45,17 +45,6 @@ namespace __gnu_test
              && Category<const volatile Type>::type::value == value);
     }
 
-  template<template<typename> class Property, typename Type>
-#if __cplusplus >= 201103L
-    constexpr
-#endif
-    bool
-    test_property(typename Property<Type>::value_type value)
-    {
-      return (Property<Type>::value == value
-             && Property<Type>::type::value == value);
-    }
-
   // For testing tr1/type_traits/extent, which has a second template
   // parameter.
   template<template<typename, unsigned> class Property,
@@ -79,6 +68,14 @@ namespace __gnu_test
       return (Property<Type1, Types...>::value == value
              && Property<Type1, Types...>::type::value == value);
     }
+#else
+  template<template<typename> class Property, typename Type>
+    bool
+    test_property(typename Property<Type>::value_type value)
+    {
+      return (Property<Type>::value == value
+             && Property<Type>::type::value == value);
+    }
 #endif
 
   template<template<typename, typename> class Relationship,