Check that a partial specialization is more specialized.
authorJason Merrill <jason@redhat.com>
Wed, 21 Dec 2016 19:38:35 +0000 (14:38 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 21 Dec 2016 19:38:35 +0000 (14:38 -0500)
* pt.c (process_partial_specialization): Use
get_partial_spec_bindings to check that the partial specialization
is more specialized than the primary template.

From-SVN: r243868

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/constexpr-data2.C
gcc/testsuite/g++.dg/cpp0x/variadic82.C
gcc/testsuite/g++.dg/cpp0x/variadic83.C
gcc/testsuite/g++.dg/template/partial5.C

index 4c68b1e4e3e9db32865fef1066c6aed9a855c19f..7faac155e3408dc100275134575c8639bdc1c61b 100644 (file)
@@ -1,5 +1,9 @@
 2016-12-21  Jason Merrill  <jason@redhat.com>
 
+       * pt.c (process_partial_specialization): Use
+       get_partial_spec_bindings to check that the partial specialization
+       is more specialized than the primary template.
+
        * pt.c (convert_template_argument): Pass args to do_auto_deduction.
        (mark_template_parm): Handle deducibility from type of non-type
        argument here.
index 9d9c35e47e6f440a1929498728e3bfa6c88d4db5..8abbcfb6f43f135b637aeb59aab6e53116c86c64 100644 (file)
@@ -4606,9 +4606,20 @@ process_partial_specialization (tree decl)
             "primary template because it replaces multiple parameters "
             "with a pack expansion");
       inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here");
+      /* Avoid crash in process_partial_specialization.  */
       return decl;
     }
 
+  /* If we aren't in a dependent class, we can actually try deduction.  */
+  else if (tpd.level == 1
+          && !get_partial_spec_bindings (maintmpl, maintmpl, specargs))
+    {
+      if (permerror (input_location, "partial specialization %qD is not "
+                    "more specialized than", decl))
+       inform (DECL_SOURCE_LOCATION (maintmpl), "primary template %qD",
+               maintmpl);
+    }
+
   /* [temp.class.spec]
 
      A partially specialized non-type argument expression shall not
index 312760a37676075b72081ec446fc71f5357504d1..898102167de83a35a34c64c3d3ef88fb0fe311bc 100644 (file)
@@ -12,7 +12,7 @@ template<typename _Tp, _Tp v>
   };
 
 // Partial specialization.
-template<typename _Tp, _Tp v>
+template<typename _Tp, _Tp* v>
   struct A3<_Tp*, v>
   {
     typedef _Tp* value_type;
index f9bbc3532685511eea418d3f087ce4d62febdc7f..9ac59cd5f4109b22bf92e5db1463ffb73967999f 100644 (file)
@@ -3,9 +3,9 @@
 
 template<typename> struct A;
 
-template<typename... T> struct A<T*...> // { dg-bogus "cannot expand" "" }
+template<typename... T> struct A<T*...> // { dg-error "" }
 {
   struct B;
 };
 
-A<void*> a; // { dg-bogus "incomplete type" "" }
+A<void*> a;
index 507fc7e4c6cedbfb95f9ebf757c8fef9f806377c..c751e7327ca9977600051f570269bd505d8c5db1 100644 (file)
@@ -3,6 +3,6 @@
 
 template<typename> struct A;
 
-template<typename... T> struct A<T...> { }; // { dg-bogus "cannot expand" "" }
+template<typename... T> struct A<T...> { }; // { dg-error "" }
 
-A<int> a; // { dg-bogus "incomplete type" "" }
+A<int> a;
index 2f400f7d44cd15d3ed3604debac1aa87f7235d20..1b56fb39fa1f64289906d514b1138ffcef96ce91 100644 (file)
@@ -14,7 +14,7 @@ template<typename T, typename T::foo V>
 struct Y { };
 
 template<typename T, typename U, U v>
-struct Y<T, v> { }; // { dg-error "not deducible|U" "" { target { ! c++1z } } }
+struct Y<T, v> { }; // { dg-error "" }
 
 
 template<typename T, T V>