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.