http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52529

             Bug #: 52529
           Summary: Compiler rejects template code inconsistently
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: scov...@gmail.com


The following code does or does not compile (with varying errors) under
4.7.0-RC20120302 and 4.6.2 depending on the choice of FIRST..FOURTH; all four
variants compile under 4.5.3. 

I've narrowed down the test case as far as I could, but I don't really
understand what's going wrong. Does the code break some subtle lookup rule
which gcc recently became more strict about? There seem to be two issues,
because either A<M> or foo() is enough to trigger an error; only A<1>::foo<T>
compiles. 

=== bug.cpp ===
template <long N> struct A {
    template <typename T> long foo(typename T::X *x);
};

template <typename T> struct B {
    typedef typename T::X X;
    enum { M=1 };
    static void bar(X *x);
};

struct C { struct X; };
int main() { B<C>::bar(0); }

template <typename T> void B<T>::bar(X *x) {
#if defined(FIRST)
    A<M>().foo(x);
#elif defined(SECOND)
    A<M>().foo<T>(x);
#elif defined(THIRD)
    A<1>().foo(x);
#elif defined(FOURTH)
    A<1>().foo<T>(x);
#endif
}
=== end bug.cpp ===


Sample error message from 4.7.0, since it has the clearest error messages
(4.6.2 gets confused by earlier errors when attempting to suggest a candidate):

**** FIRST ****
bug.cpp: In instantiation of ‘static void B<T>::bar(B<T>::X*) [with T = C;
B<T>::X = C::X]’:
bug.cpp:12:20:   required from here
bug.cpp:16:5: error: no matching function for call to ‘A<1l>::foo(B<C>::X*&)’
bug.cpp:16:5: note: candidate is:
bug.cpp:2:32: note: template<class T> long int A::foo(typename T::X*) [with T =
T; long int N = 1l]
bug.cpp:2:32: note:   template argument deduction/substitution failed:
bug.cpp:16:5: note:   couldn't deduce template parameter ‘T’

**** SECOND ****
bug.cpp: In static member function ‘static void B<T>::bar(B<T>::X*)’:
bug.cpp:18:17: error: expected primary-expression before ‘>’ token

**** THIRD ****
bug.cpp: In instantiation of ‘static void B<T>::bar(B<T>::X*) [with T = C;
B<T>::X = C::X]’:
bug.cpp:12:20:   required from here
bug.cpp:20:5: error: no matching function for call to ‘A<1l>::foo(B<C>::X*&)’
bug.cpp:20:5: note: candidate is:
bug.cpp:2:32: note: template<class T> long int A::foo(typename T::X*) [with T =
T; long int N = 1l]
bug.cpp:2:32: note:   template argument deduction/substitution failed:
bug.cpp:20:5: note:   couldn't deduce template parameter ‘T’

**** FOURTH ****
[successful compilation]

Reply via email to