Re: [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.

2014-11-18 Thread Jason Merrill

On 11/12/2014 06:53 AM, Markus Trippelsdorf wrote:

Anyway, I will defer working on this until next stage1, because I don't
have time to implement this before stage1 closes on Saturday.


I think this should be OK for stage 3, especially given that you first 
sent the patch before the end of stage 1.


Jason




Re: [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.

2014-11-11 Thread Jason Merrill

On 11/08/2014 06:57 AM, Markus Trippelsdorf wrote:

+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
@@ -7,9 +7,9 @@
 // the template

 namespace N {
-  template class T class foo;  // { dg-error  } referenced below
+  template class T class foo;  // { dg-error   { target { ! c++11 } } } 
referenced below
 }

 using namespace N;

-template  class foovoid; // { dg-error  } invalid specialization
+template  class foovoid; // { dg-error   { target { ! c++11 } } } 
invalid specialization


This should still get an error in C++11 mode.

I think we also need to test this:

namespace A {
  namespace B {
template class T void f();
  }
  using namespace B;
}

template void A::f(); // { dg-error  }

I think your code won't catch this, because we need to know what the 
explicit namespace was, not just whether there was one.


Can we handle this in check_explicit_specialization rather than all the 
way down in register_specialization?


Jason



Re: [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.

2014-11-11 Thread Markus Trippelsdorf
On 2014.11.11 at 10:11 -0500, Jason Merrill wrote:
 On 11/08/2014 06:57 AM, Markus Trippelsdorf wrote:
  +++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
  @@ -7,9 +7,9 @@
   // the template
 
   namespace N {
  -  template class T class foo;// { dg-error  } referenced below
  +  template class T class foo;// { dg-error   { target { ! c++11 
  } } } referenced below
   }
 
   using namespace N;
 
  -template  class foovoid; // { dg-error  } invalid specialization
  +template  class foovoid; // { dg-error   { target { ! c++11 } } } 
  invalid specialization
 
 This should still get an error in C++11 mode.

Both EGG and clang currently accept it. 

 I think we also need to test this:
 
 namespace A {
namespace B {
  template class T void f();
}
using namespace B;
 }
 
 template void A::f(); // { dg-error  }

 I think your code won't catch this, because we need to know what the 
 explicit namespace was, not just whether there was one.

This is already caught:
 error: template-id ‘f’ for ‘void A::f()’ does not match any template 
declaration

 Can we handle this in check_explicit_specialization rather than all the 
 way down in register_specialization?

I will look into it.

-- 
Markus


Re: [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.

2014-11-11 Thread Mike Stump
On Nov 11, 2014, at 7:37 AM, Markus Trippelsdorf mar...@trippelsdorf.de wrote:
 Both EGG and clang currently accept it. 

EDG…  I think you mean.

Re: [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.

2014-11-11 Thread Jason Merrill

On 11/11/2014 10:37 AM, Markus Trippelsdorf wrote:

On 2014.11.11 at 10:11 -0500, Jason Merrill wrote:

On 11/08/2014 06:57 AM, Markus Trippelsdorf wrote:

+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
@@ -7,9 +7,9 @@
  // the template

  namespace N {
-  template class T class foo;  // { dg-error  } referenced below
+  template class T class foo;  // { dg-error   { target { ! c++11 } } } 
referenced below
  }

  using namespace N;

-template  class foovoid; // { dg-error  } invalid specialization
+template  class foovoid; // { dg-error   { target { ! c++11 } } } 
invalid specialization


This should still get an error in C++11 mode.


Both EGG and clang currently accept it.


EDG rejects it in strict mode.

Jason



Re: [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.

2014-11-11 Thread Markus Trippelsdorf
On 2014.11.11 at 13:39 -0500, Jason Merrill wrote:
 On 11/11/2014 10:37 AM, Markus Trippelsdorf wrote:
  On 2014.11.11 at 10:11 -0500, Jason Merrill wrote:
  On 11/08/2014 06:57 AM, Markus Trippelsdorf wrote:
  +++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
  @@ -7,9 +7,9 @@
// the template
 
namespace N {
  -  template class T class foo;  // { dg-error  } referenced below
  +  template class T class foo;  // { dg-error   { target { ! c++11 
  } } } referenced below
}
 
using namespace N;
 
  -template  class foovoid; // { dg-error  } invalid specialization
  +template  class foovoid; // { dg-error   { target { ! c++11 } } 
  } invalid specialization
 
  This should still get an error in C++11 mode.
 
  Both EGG and clang currently accept it.
 
 EDG rejects it in strict mode.

They also reject g++.dg/template/spec36.C and
g++.old-deja/g++.pt/lookup10.C with -strict-ansi -std=c++11.
Which is kind of ironical given that two of their employees worked on
the issue:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3064.pdf

-- 
Markus


Re: [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.

2014-11-11 Thread Jason Merrill

On 11/11/2014 03:06 PM, Markus Trippelsdorf wrote:

On 2014.11.11 at 13:39 -0500, Jason Merrill wrote:

On 11/11/2014 10:37 AM, Markus Trippelsdorf wrote:

On 2014.11.11 at 10:11 -0500, Jason Merrill wrote:

On 11/08/2014 06:57 AM, Markus Trippelsdorf wrote:

+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
@@ -7,9 +7,9 @@
   // the template

   namespace N {
-  template class T class foo;  // { dg-error  } referenced below
+  template class T class foo;  // { dg-error   { target { ! c++11 } } } 
referenced below
   }

   using namespace N;

-template  class foovoid; // { dg-error  } invalid specialization
+template  class foovoid; // { dg-error   { target { ! c++11 } } } 
invalid specialization


This should still get an error in C++11 mode.


Both EGG and clang currently accept it.


EDG rejects it in strict mode.


They also reject g++.dg/template/spec36.C and
g++.old-deja/g++.pt/lookup10.C with -strict-ansi -std=c++11.
Which is kind of ironical given that two of their employees worked on
the issue:


Yeah, sometimes implementation lags behind drafting... :)

In any case, I think the standard is clear that this should get an 
error, and the EDG and Clang implementers agree with me.


Jason



[PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.

2014-11-08 Thread Markus Trippelsdorf
DR374: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374
allows explicit specialization of templates in the enclosing namespace.

This is implemented by consolidating check_specialization_namespace and
check_explicit_instantiation_namespace into a new function and
pedwarning only for C++98. Only explicit namespace qualifications are
accepted, so g++.dg/template/spec17.C is rejected. To check for this
condition have_def and in_namespace are passed through to
register_specialization() by using a bitmask.

Tested on powerpc64-unknown-linux-gnu. (Also tested by running the Boost
testsuite and building Firefox.)

OK for trunk?

Thanks again.

2014-11-08  Markus Trippelsdorf  mar...@trippelsdorf.de

gcc/cp/ChangeLog:

* decl.c (grokfndecl): Also pass through in_namespace.
* pt.c (check_instant_or_special_namespace): Consolidate
check_specialization_namespace and
check_explicit_instantiation_namespace. pedwarn only for C++98.
(maybe_process_partial_specialization): Call consolidated
function.
(register_specialization): Add flag. Only accept explicit
namespace qualification. 
(check_template_variable): Call consolidated function.
(check_explicit_specialization): Likewise
(push_template_decl_real): Likewise
(tsubst_friend_function): Likewise.
(tsubst_decl): Likewise.
(do_decl_instantiation): Likewise.
(do_type_instantiation): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/template/spec17.C: Don't dg-error for C++11 and up.
* g++.dg/template/spec25.C: Likewise. Adjust regex.
* g++.dg/template/spec36.C: Don't dg-error for C++11 and up.
* g++.old-deja/g++.ns/template13.C: Likewise.
* g++.old-deja/g++.pt/explicit73.C: Likewise.
* g++.old-deja/g++.pt/lookup10.C: Likewise.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 4abc1011e61e..931bf2c2aafc 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7855,7 +7855,8 @@ grokfndecl (tree ctype,
   decl = check_explicit_specialization (orig_declarator, decl,
template_count,
2 * funcdef_flag +
-   4 * (friendp != 0));
+   4 * (friendp != 0) +
+   8 * (in_namespace != 0));
   if (decl == error_mark_node)
 return NULL_TREE;
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index fa9652f748c2..64f72e50880d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -755,57 +755,58 @@ end_explicit_instantiation (void)
   processing_explicit_instantiation = false;
 }
 
-/* An explicit specialization or partial specialization of TMPL is being
-   declared.  Check that the namespace in which the specialization is
-   occurring is permissible.  Returns false iff it is invalid to
-   specialize TMPL in the current namespace.  */
+/* If specialization is true, an explicit specialization or partial
+   specialization of TMPL is being declared.  Check that the namespace
+   in which the specialization is occurring is permissible.  Returns
+   false iff it is invalid to specialize TMPL in the current namespace.
+   If specialization is false, TMPL is an explicit instantiation.
+   Check that it is valid to perform this explicit instantiation in
+   the current namespace.  */
 
 static bool
-check_specialization_namespace (tree tmpl)
+check_instant_or_special_namespace (tree tmpl, bool specialization)
 {
   tree tpl_ns = decl_namespace_context (tmpl);
 
-  /* [tmpl.expl.spec]
-
- An explicit specialization shall be declared in the namespace of
- which the template is a member, or, for member templates, in the
- namespace of which the enclosing class or enclosing class
- template is a member.  An explicit specialization of a member
- function, member class or static data member of a class template
- shall be declared in the namespace of which the class template is
- a member.  */
-  if (current_scope() != DECL_CONTEXT (tmpl)
-   !at_namespace_scope_p ())
-{
-  error (specialization of %qD must appear at namespace scope, tmpl);
-  return false;
-}
-  if (is_associated_namespace (current_namespace, tpl_ns))
-/* Same or super-using namespace.  */
-return true;
-  else
+  if (specialization)
 {
-  permerror (input_location, specialization of %qD in different 
namespace, tmpl);
-  permerror (input_location,   from definition of %q+#D, tmpl);
-  return false;
-}
-}
+  /* [tmpl.expl.spec]
 
-/* SPEC is an explicit instantiation.  Check that it is valid to
-   perform this explicit instantiation in the current namespace.  */
-
-static void
-check_explicit_instantiation_namespace (tree spec)
-{
-  tree ns;
+An explicit specialization shall be declared in the namespace of
+which the template is a member, or, for member templates, in the
+namespace of 

[PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.

2014-11-02 Thread Markus Trippelsdorf
DR374: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374
allows explicit specialization of templates in the enclosing namespace.
Because this idiom is currently already accepted with -fpermissive, the
fix is easy: Just skip the calls to permerror() for C++11 and up.

Tested on powerpc64-unknown-linux-gnu.
OK for trunk?

Thanks.

2014-11-02  Markus Trippelsdorf  mar...@trippelsdorf.de

DR 374
PR c++/56480
* pt.c (check_specialization_namespace): Skip permerror()
for C++11 and up.

DR 374
PR c++/56480
* g++.dg/template/spec17.C: Don't dg-error for C++11 and up.
* g++.dg/template/spec25.C: Likewise.
* g++.dg/template/spec36.C: Likewise.
* g++.old-deja/g++.ns/template13.C: Likewise.
* g++.old-deja/g++.pt/explicit73.C: Likewise.
* g++.old-deja/g++.pt/lookup10.C: Likewise.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2cf10f442f68..09a545496fa8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -785,8 +785,12 @@ check_specialization_namespace (tree tmpl)
 return true;
   else
 {
-  permerror (input_location, specialization of %qD in different 
namespace, tmpl);
-  permerror (input_location,   from definition of %q+#D, tmpl);
+  if (cxx_dialect  cxx11)
+   {
+ permerror (input_location, specialization of %qD in different 
+namespace, tmpl);
+ permerror (input_location,   from definition of %q+#D, tmpl);
+   }
   return false;
 }
 }
diff --git a/gcc/testsuite/g++.dg/template/spec17.C 
b/gcc/testsuite/g++.dg/template/spec17.C
index 237557684238..70e5be28e05a 100644
--- a/gcc/testsuite/g++.dg/template/spec17.C
+++ b/gcc/testsuite/g++.dg/template/spec17.C
@@ -1,11 +1,11 @@
 // PR c++/16224
 
 namespace io { 
-  template typename int foo(); // { dg-error  }
+  template typename int foo(); // { dg-error   { target { ! c++11 } } }
 } 
  
 using namespace io; 
  
-template int fooint(); // { dg-error  }
+template int fooint(); // { dg-error   { target { ! c++11 } } }
  
 int a = fooint(); 
diff --git a/gcc/testsuite/g++.dg/template/spec25.C 
b/gcc/testsuite/g++.dg/template/spec25.C
index 385d19ada0c4..d41c5fce1297 100644
--- a/gcc/testsuite/g++.dg/template/spec25.C
+++ b/gcc/testsuite/g++.dg/template/spec25.C
@@ -1,10 +1,10 @@
 namespace N {
   template typename T
   struct S {
-void f() {}// { dg-error definition }
+void f() {}// { dg-error definition  { target 
{ ! c++11 } } }
   };
 }
 
 namespace K {
-  template  void N::Schar::f() {} // { dg-error different namespace }
+  template  void N::Schar::f() {} // { dg-error different namespace  { 
target { ! c++11 } } }
 }
diff --git a/gcc/testsuite/g++.dg/template/spec36.C 
b/gcc/testsuite/g++.dg/template/spec36.C
index 7e8dc5241d9f..d9c57824b7e5 100644
--- a/gcc/testsuite/g++.dg/template/spec36.C
+++ b/gcc/testsuite/g++.dg/template/spec36.C
@@ -8,9 +8,9 @@ struct basic_string
 namespace MyNS {
   class MyClass {
 template typename T
-T test() { } /* { dg-error from definition } */
+T test() { } /* { dg-error from definition  { target { ! c++11 } } } */
   };
 }
 template 
-basic_string MyNS::MyClass::test() /* { dg-error specialization of } */
+basic_string MyNS::MyClass::test() /* { dg-error specialization of  { 
target { ! c++11 } } } */
 { return 1; }
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/template13.C 
b/gcc/testsuite/g++.old-deja/g++.ns/template13.C
index a9559c7153b6..21ad61847b73 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/template13.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/template13.C
@@ -4,18 +4,18 @@ namespace bar
 {
   // trick it to provide some prior declaration
   templateclass T
-  void foo(); // { dg-error definition }
+  void foo(); // { dg-error definition  { target { ! c++11 } } }
   templateclass Tclass X; // { dg-message note: previous declaration }
 }
 
 template typename T
 T const
-bar::foo(T const a) // { dg-error   { xfail *-*-* } } not declared in 
bar - 
+bar::foo(T const a)// { dg-error   { xfail *-*-* } } not declared in 
bar -
 {
   return a;
 }
 
-template void bar::fooint() // { dg-error different namespace }
+template void bar::fooint() // { dg-error different namespace  { 
target { ! c++11 } } }
 {
 }
 
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C 
b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
index 1d83e3468289..bcf4fe7f21a5 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit73.C
@@ -7,9 +7,9 @@
 // the template
 
 namespace N {
-  template class T class foo;// { dg-error  } referenced below
+  template class T class foo;// { dg-error   { target { ! c++11 
} } } referenced below
 }
 
 using namespace N;
 
-template  class foovoid; // { dg-error  } invalid specialization
+template  class foovoid; // { dg-error   { target { ! c++11 } } } 
invalid specialization
diff --git 

Re: [PATCH] Fix PR56480 aka DR374. Allow explicit specialization in enclosing namespace.

2014-11-02 Thread Markus Trippelsdorf
On 2014.11.02 at 13:58 +0100, Markus Trippelsdorf wrote:
 diff --git a/gcc/testsuite/g++.dg/template/spec25.C 
 b/gcc/testsuite/g++.dg/template/spec25.C
 index 385d19ada0c4..d41c5fce1297 100644
 --- a/gcc/testsuite/g++.dg/template/spec25.C
 +++ b/gcc/testsuite/g++.dg/template/spec25.C
 @@ -1,10 +1,10 @@
  namespace N {
template typename T
struct S {
 -void f() {}  // { dg-error definition }
 +void f() {}  // { dg-error definition  { target 
 { ! c++11 } } }
};
  }
  
  namespace K {
 -  template  void N::Schar::f() {} // { dg-error different namespace }
 +  template  void N::Schar::f() {} // { dg-error different namespace  
 { target { ! c++11 } } }
  }

Hmm, I think this testcase should actually be rejected even with C++11.

-- 
Markus