Hi, all!
The following code (reduced from wide-int.h) is rejected by Intel C++ Compiler
(EDG-based):

$ cat genpreds1_min.cc
template <typename>
class A;

template <int>
struct B;

template <typename>
struct C;

template <>
template <int N>
struct C <B <N> >
{
    template<typename T>
    A <B <N> >
    m_fn(T);
};

template <int N>
template <typename T>
A <B <N> >
C <B <N> >::m_fn (T)
{
}

$ /opt/intel/bin/icpc -c genpreds1_min.cc
genpreds1_min.cc(22): error: incomplete type is not allowed
  C <B <N> >::m_fn (T)
  ^

genpreds1_min.cc(22): error: template argument list must match the parameter 
list
  C <B <N> >::m_fn (T)

Clang gives the following warning:

$ clang++ -c genpreds1_min.cc
genpreds1_min.cc:10:1: warning: extraneous template parameter list in template
specialization
template <>

I think that the warning is correct, and "template <>" should not be used here.
The attached patch should fix this issue. Bootstrapped and regtested on
x86_64-linux. OK for trunk?

-- 
Regards,
    Mikhail Maltsev
diff --git a/gcc/wide-int.h b/gcc/wide-int.h
index d8f7b46..6e0275f 100644
--- a/gcc/wide-int.h
+++ b/gcc/wide-int.h
@@ -360,21 +360,18 @@ namespace wi
      inputs.  Note that CONST_PRECISION and VAR_PRECISION cannot be
      mixed, in order to give stronger type checking.  When both inputs
      are CONST_PRECISION, they must have the same precision.  */
-  template <>
   template <typename T1, typename T2>
   struct binary_traits <T1, T2, FLEXIBLE_PRECISION, FLEXIBLE_PRECISION>
   {
     typedef widest_int result_type;
   };
 
-  template <>
   template <typename T1, typename T2>
   struct binary_traits <T1, T2, FLEXIBLE_PRECISION, VAR_PRECISION>
   {
     typedef wide_int result_type;
   };
 
-  template <>
   template <typename T1, typename T2>
   struct binary_traits <T1, T2, FLEXIBLE_PRECISION, CONST_PRECISION>
   {
@@ -384,14 +381,12 @@ namespace wi
 			       <int_traits <T2>::precision> > result_type;
   };
 
-  template <>
   template <typename T1, typename T2>
   struct binary_traits <T1, T2, VAR_PRECISION, FLEXIBLE_PRECISION>
   {
     typedef wide_int result_type;
   };
 
-  template <>
   template <typename T1, typename T2>
   struct binary_traits <T1, T2, CONST_PRECISION, FLEXIBLE_PRECISION>
   {
@@ -401,7 +396,6 @@ namespace wi
 			       <int_traits <T1>::precision> > result_type;
   };
 
-  template <>
   template <typename T1, typename T2>
   struct binary_traits <T1, T2, CONST_PRECISION, CONST_PRECISION>
   {
@@ -412,7 +406,6 @@ namespace wi
 			       <int_traits <T1>::precision> > result_type;
   };
 
-  template <>
   template <typename T1, typename T2>
   struct binary_traits <T1, T2, VAR_PRECISION, VAR_PRECISION>
   {
@@ -876,7 +869,6 @@ generic_wide_int <storage>::dump () const
 
 namespace wi
 {
-  template <>
   template <typename storage>
   struct int_traits < generic_wide_int <storage> >
     : public wi::int_traits <storage>
@@ -955,7 +947,6 @@ inline wide_int_ref_storage <SE>::wide_int_ref_storage (const T &x,
 
 namespace wi
 {
-  template <>
   template <bool SE>
   struct int_traits <wide_int_ref_storage <SE> >
   {
@@ -1142,7 +1133,6 @@ public:
 
 namespace wi
 {
-  template <>
   template <int N>
   struct int_traits < fixed_wide_int_storage <N> >
   {
gcc/ChangeLog:

2015-07-17  Mikhail Maltsev  <malts...@gmail.com>

        * wide-int.h (struct binary_traits): Fix partial specialization syntax.
        (struct int_traits): Likewise.

Reply via email to