<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - partial specialization selection treated as immediate context, resulting in invalid decls with no diagnostic"
   href="https://bugs.llvm.org/show_bug.cgi?id=50723">50723</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>partial specialization selection treated as immediate context, resulting in invalid decls with no diagnostic
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

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

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </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>blitzrakete@gmail.com, dgregor@apple.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Clang incorrectly accepts this code, despite S<int*, int*> having no member
named 'foo':

template<typename T, typename U> struct S {};
template<typename T> struct S<T, T> {};
template<typename T, typename U> struct S<T*, U*> {};
template<typename ... Ts> using V = void;
template<typename T, typename U = void> struct X {}; // #1
template<typename T> struct X<T, V<typename S<T, T>::type>>; // #2
X<int*> xpi;
S<int*, int*>::foo x = "hello";

What's happening here is that we try to instantiate S<int*, int*> as part of
considering #2, but fail because the partial specialization selection for S
results in an ambiguity. We mark S<int*, int*> as invalid and produce a
diagnostic. However, because this all happens in the immediate context of the
partial specialization selection for #2, we swallow the diagnostic and instead
select #1.

Then when we try to form S<int*, int*>::foo, because S<int*, int*> is marked as
invalid we form an invalid type and don't produce any diagnostic (incorrectly
thinking we already produced one).

Probably the right approach here is to treat ambiguity during partial
specialization selection as not being part of the immediate context. That's
what GCC and EDG do. (MSVC, like Clang, treats this ambiguity as being in the
immediate context, and has very similar kinds of brokenness for examples like
this one.)</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>