Message ID | AANLkTimZXYODVo2CHZnS=mCitoW_xrG4xia5in6tskg9@mail.gmail.com |
---|---|
State | New |
Headers | show |
On 10/01/2010 05:18 PM, Jonathan Wakely wrote: > Can anyone point me in the right direction so that the new test in the > patch fails, but those don't? This restriction has been clarified in the current working paper to read "An explicit specialization shall be declared in a namespace enclosing the specialized template. An explicit specialization whose declarator-id is not qualified shall be declared in the nearest enclosing namespace of the template, or, if the namespace is inline (7.3.1), any namespace from its enclosing namespace set." ...which is what makes g++.ns/template12.C well-formed. It seems that check_specialization_namespace doesn't have the information it needs; it doesn't know whether the specialization was declared with a qualified-id (as in template12.C). I would guess that memtemp96.C is failing because we pushed into A<char> as part of parsing the declarator, which makes current_scope() give the wrong answer. It seems you need to do the checking at a higher level. Maybe in check_explicit_specialization. Jason
Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 164893) +++ gcc/cp/pt.c (working copy) @@ -1379,6 +1379,11 @@ register_specialization (tree spec, tree } else if (DECL_TEMPLATE_SPECIALIZATION (fn)) { + /* A specialization must be declared in the same namespace as the + template it is specializing. */ + if (!check_specialization_namespace (tmpl)) + return error_mark_node; + if (!duplicate_decls (spec, fn, is_friend) && DECL_INITIAL (spec)) /* Dup decl failed, but this is a new definition. Set the line number so any errors match this new Index: gcc/testsuite/g++.dg/template/pr42018.C =================================================================== --- gcc/testsuite/g++.dg/template/pr42018.C (revision 0) +++ gcc/testsuite/g++.dg/template/pr42018.C (revision 0) @@ -0,0 +1,14 @@ +// PR c++/42018 +// { dg-do compile } + +template<typename> + void foo(void); // { dg-error "from definition of" } + +template<> + void foo<int>(); + +namespace x { + template<> + void foo<int>() { return; } // { dg-error "in different namespace" } +} +