<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Sep 23, 2014 at 8:57 AM, Marco <span dir="ltr"><<a href="mailto:marco.diiga@gmail.com" target="_blank">marco.diiga@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">I'm taking a look at a possible clang issue with the following code:<br>
___________________________<br>
struct incomplete;<br>
<br>
template<class T><br>
struct A { T d; };<br>
<br>
template <class T><br>
struct B { };<br>
<br>
template<typename T> void func(T &t);<br>
<br>
int main() {<br>
    B<A&lt;incomplete>> a, b;<br>
    a = b;<br>
}<br>
___________________________<br>
<br>
<br>
this code causes clang to emit an error "incomplete type T d;". I searched<br>
in the cpp standard and found nothing related to ADL causing an implicit<br>
instantiation in this case.</blockquote><div><br></div><div>Here it is:</div><div><br></div><div>[basic.lookup.argdep]/2:</div><div><br></div><div>"[...] if T is a class template specialization, its associated [...] classes also include: the [...] classes associated with the types of the template arguments provided for template type parameters [...]"</div><div><br></div><div>[basic.lookup.argdep]/4:</div><div><br></div><div><div>"When considering an associated namespace, the lookup is the same as the lookup performed when the associated namespace is used as a qualifier (3.4.3.2) except that:</div><div>[...] Any namespace-scope friend functions or friend function templates declared in associated classes are visible within their respective namespaces even if they are not visible during an ordinary lookup (11.3)"</div></div><div><br></div><div>[temp.inst]/1:</div><div><br></div><div>"Unless a class template specialization has been explicitly instantiated (14.7.2) or explicitly specialized (14.7.3), the class template specialization is implicitly instantiated [...] when the completeness of the class type affects the semantics of the program."</div><div><br></div><div>The completeness of the class type can affect whether friends are declared in an associated class, which therefore affects the semantics of the program. Therefore ADL triggers the implicit instantiation of all associated classes, and A<incomplete> is an associated class of B<A<incomplete>>.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">So I started researching clang's source and I<br>
believe this is what is happening:<br>
<br>
- ADL process starts<br></blockquote><div><br></div><div>This seems like the interesting part. Why are we performing ADL? There can be no non-member operator= functions (other than the builtin ones, which are not found by ADL). [over.match.oper]/3.2 says:</div><div><br></div><div>"The set of non-member candidates is the result of the unqualified lookup of operator@ in the context of the expression according to the usual rules for name lookup in unqualified function calls (3.4.2) except that all member functions are ignored."</div><div><br></div><div>The implication is that we don't perform this lookup (and thus do not perform ADL) if there is no non-member form in Table 11, but that's not explicitly stated. In any case, we're /permitted/ to skip this due to [temp.inst]p7: "If the overload resolution process can determine the correct function to call without instantiating a class template definition, it is unspecified whether that instantiation actually takes place."</div><div><br></div><div>Anyway, fixed in r218330 by skipping ADL in this case. I'm also taking this to the C++ committee to see if we can get the rules clarified here.<br></div><div><br></div><div>(GCC gets this wrong for operator[] and operator-> too; Clang already did the right thing there.)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
- A<incomplete> is tried to be instantiated to have a better ADL set (and<br>
also for other reasons as explained here:<br>
<a href="http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20140310/101487.html" target="_blank">http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20140310/101487.html</a><br>
) with a "complain = false" flag (so it won't complain if the template can't<br>
be instantiated)<br>
- The flag is lost during instantiation of the template members, I'm posting<br>
the entire MSVC stack trace here: <a href="http://nopaste.info/829f7404e6.html" target="_blank">http://nopaste.info/829f7404e6.html</a><br>
<br>
I spoke with David Blaikie about this issue and told me to give it a wider<br>
audience here.<br>
<br>
What is strange to me is that also gcc behaves in the same way as clang, so<br>
it might as well mean that I'm getting something wrong and clang/gcc are<br>
both correct in this.<br>
<br>
<br>
<br>
--<br>
View this message in context: <a href="http://clang-developers.42468.n3.nabble.com/ADL-causing-implicit-template-class-instantiation-failure-tp4041705.html" target="_blank">http://clang-developers.42468.n3.nabble.com/ADL-causing-implicit-template-class-instantiation-failure-tp4041705.html</a><br>
Sent from the Clang Developers mailing list archive at Nabble.com.<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
</blockquote></div><br></div></div>