Patchwork c++/42018 try to reject specialization re-declared in wrong namespace

login
register
mail settings
Submitter Jonathan Wakely
Date Oct. 1, 2010, 9:18 p.m.
Message ID <AANLkTimZXYODVo2CHZnS=mCitoW_xrG4xia5in6tskg9@mail.gmail.com>
Download mbox | patch
Permalink /patch/66520/
State New
Headers show

Comments

Jonathan Wakely - Oct. 1, 2010, 9:18 p.m.
This patch is my attempt to fix PR c++/42018, but it's wrong, because
it also rejects some valid specializations, causing:

FAIL: g++.old-deja/g++.ns/template12.C (test for excess errors)
Excess errors:
/home/redi/src/gcc/gcc-4.x/gcc/testsuite/g++.old-deja/g++.ns/template12.C:18:47:
error: specialization of 'template<class T> const T bar::foo(const
T&)' in different namespace [-fpermissive]
/home/redi/src/gcc/gcc-4.x/gcc/testsuite/g++.old-deja/g++.ns/template12.C:13:20:
error:   from definition of 'template<class T> const T bar::foo(const
T&)' [-fpermissive]

FAIL: g++.old-deja/g++.pt/memtemp96.C (test for excess errors)
Excess errors:
/home/redi/src/gcc/gcc-4.x/gcc/testsuite/g++.old-deja/g++.pt/memtemp96.C:11:17:
error: specialization of 'template<class T> template<class U> int
A::f(U)' must appear at namespace scope

Can anyone point me in the right direction so that the new test in the
patch fails, but those don't?

Thanks,

Jonathan
Jason Merrill - Oct. 4, 2010, 2:31 p.m.
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

Patch

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" }
+}
+