<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - spurious diagnostic produced for second use of ill-formed function template specialization"
   href="http://llvm.org/bugs/show_bug.cgi?id=21422">21422</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>spurious diagnostic produced for second use of ill-formed function template specialization
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>richard-llvm@metafoo.co.uk
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Testcase:

template<typename T> struct A {
  A() { T::error; }
};
struct B : A<int> {};
template<typename T> struct C : A<T> { C() : A<int>() {} };
B b;
C<int> c;

This produces:

<stdin>:2:9: error: type 'int' cannot be used prior to '::' because it has no
members
  A() { T::error; }
        ^
<stdin>:4:8: note: in instantiation of member function 'A<int>::A' requested
here
struct B : A<int> {};
       ^
<stdin>:5:46: error: no matching constructor for initialization of 'A<int>'
template<typename T> struct C : A<T> { C() : A<int>() {} };
                                             ^
<stdin>:6:13: note: in instantiation of member function 'C<int>::C' requested
here
B b; C<int> c;
            ^
<stdin>:1:29: note: candidate constructor (the implicit copy constructor) not
viable: requires 1 argument, but 0 were provided
template<typename T> struct A {
                            ^

The first error is fine; the second one is bogus. Two issues here:

1) we shouldn't be marking the declaration of the function as invalid just
because we failed to instantiate its definition (but currently this is how we
track that we shouldn't try to instantiate it again, so we'll need another
representation for that if we change this), and
2) if the candidate set contains invalid functions, overload resolution should
always succeed (rather than ignoring those functions), since as far as we know
one of those invalid functions could be intended to match.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>