+2004-07-21 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/14497
+ * pt.c (check_explicit_specialization): Remove extension to accept
+ specializations without template headers. Fall-through to normal
+ processing.
+
2004-07-21 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/509
break;
case tsk_excessive_parms:
- error ("too many template parameter lists in declaration of `%D'",
- decl);
- return error_mark_node;
+ case tsk_insufficient_parms:
+ if (tsk == tsk_excessive_parms)
+ error ("too many template parameter lists in declaration of `%D'",
+ decl);
+ else if (template_header_count)
+ error("too few template parameter lists in declaration of `%D'",
+ decl);
+ else
+ error("explicit specialization of `%D' must be introduced by "\r
+ "`template <>'", decl);\r
/* Fall through. */
case tsk_expl_spec:
else
specialization = 1;
break;
-
- case tsk_insufficient_parms:
- if (template_header_count)
- {
- error("too few template parameter lists in declaration of `%D'",
- decl);
- return decl;
- }
- else if (ctype != NULL_TREE
- && !TYPE_BEING_DEFINED (ctype)
- && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)
- && !is_friend)
- {
- /* For backwards compatibility, we accept:
-
- template <class T> struct S { void f(); };
- void S<int>::f() {} // Missing template <>
-
- That used to be valid C++. */
- if (pedantic)
- pedwarn
- ("explicit specialization not preceded by `template <>'");
- specialization = 1;
- SET_DECL_TEMPLATE_SPECIALIZATION (decl);
- }
- break;
case tsk_template:
if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
--- /dev/null
+// { dg-do compile }
+// Contributed by Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
+// PR c++/14497: Reject specialization without template headers
+
+template <int N>
+struct A {
+ template<int M> void B () ;
+};
+
+void A<0>::B<0>() { // { dg-error "explicit specialization" }
+}
+++ /dev/null
-// { dg-do run }
-// { dg-options "" }
-// Test for obsolete specialization syntax. Turn off -pedantic.
-
-#include <iostream>
-#include <typeinfo>
-
-template <typename T>
-class A {
-public:
- void test ();
-};
-
-template <typename T>
-void
-A<T>::test(){
- std::cerr << "test for " << typeid(*this).name() << std::endl;
-}
-// Specialization declaration
-template <>
-void
-A<double>::test();
-
-// Specialization definition
-void
-A<double>::test(){
- std::cerr << "specialization for " << typeid(*this).name() << std::endl;
-}
-
-
-int
-main(){
- A<int> ai;
- A<double> ad;
- ai.test();
- ad.test();
- return 0;
-}
-
-