<div>Reduced testcase:</div><div><br></div>template<typename T> struct A { typedef decltype(T() + 0) type; };<div>template<typename T> struct B {</div><div> struct C { typedef typename A<C*>::type type; };</div>
<div> typedef typename A<C*>::type type;</div><div>};</div><div>B<int> b;</div><div><br></div><div>... produces ...</div><div><br></div><div><div><stdin>:3:38: error: no type named 'type' in 'A<B<int>::C *>'</div>
<div> struct C { typedef typename A<C*>::type type; };</div><div> ~~~~~~~~~~~~~~~~^~~~</div><div><stdin>:1:54: note: in instantiation of member class 'B<int>::C' requested here</div>
<div>template<typename T> struct A { typedef decltype(T() + 0) type; };</div><div> ^</div><div><stdin>:4:20: note: in instantiation of template class 'A<B<int>::C *>' requested here</div>
<div> typedef typename A<C*>::type type;</div><div> ^</div><div><stdin>:6:8: note: in instantiation of template class 'B<int>' requested here</div><div>B<int> b;</div><div>
^</div></div><div><br></div><div>I think it would be worth filing this as a diagnostic QoR issue. We should be able to say something like</div><div><br></div><div><div><stdin>:3:38: error: member 'type' of 'A<B<int>::C *>' required recursively within the instantiation of 'A<B<int>::C *>', but it has not been instantiated yet</div>
<div><br></div><div class="gmail_quote">On Fri, Sep 28, 2012 at 7:51 AM, Howard Hinnant <span dir="ltr"><<a href="mailto:hhinnant@apple.com" target="_blank">hhinnant@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
That is one evil bug!<br>
<br>
I just tested it against tip-of-trunk clang and it appears to be fixed there (just fyi for everyone).<br>
<span class="HOEnZb"><font color="#888888"><br>
Howard<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
On Sep 27, 2012, at 7:17 PM, Adam Peterson <<a href="mailto:alpha.eta.pi@gmail.com">alpha.eta.pi@gmail.com</a>> wrote:<br>
<br>
> Is this a relevant location to provide information about what I<br>
> believe is a compiler bug in clang? If not, please forgive me for<br>
> posting it here. (Perhaps you can redirect me to some place more<br>
> appropriate.) If so, here are the details:<br>
><br>
> I have a short 15-line C++ program using only one standard header that<br>
> clang fails to compile properly under C++11 with the new standard<br>
> library (although the code itself doesn't use any C++11-specific<br>
> syntax), but G++ (4.6-Ubuntu and 4.2-Darwin) compiles it fine:<br>
><br>
> #include <map><br>
> using std::map;<br>
><br>
> template<typename K><br>
> struct Templ8 {<br>
> struct Member {<br>
> typename map<K,Member*>::iterator it;<br>
> };<br>
> typedef typename map<K,Member*>::iterator iterator_type;<br>
> };<br>
><br>
> int main() {<br>
> Templ8<int> test;<br>
> }<br>
><br>
><br>
><br>
> This is the command-line:<br>
> clang++ -stdlib=libc++ -std=c++11 main_bug.cpp<br>
> If either of the flags are removed (to compile in C++03 mode, or to<br>
> use the non-clang standard library), the code compiles. If the<br>
> typedef is removed or commented out, clang++ compiles the code fine.<br>
> If the typedef is moved inside the "Member" inner class, the code<br>
> compiles fine (even if a second typedef pulls the symbol back into the<br>
> main template scope).<br>
><br>
> My clang version information:<br>
> Apple clang version 4.1 (tags/Apple/clang-421.11.65) (based on LLVM 3.1svn)<br>
> Target: x86_64-apple-darwin12.2.0<br>
> Thread model: posix<br>
><br>
> The error output:<br>
><br>
> main_bug.cpp:7:34: error: no type named 'iterator' in<br>
> 'std::__1::map<int, Templ8<int>::Member *, std::__1::less<int>,<br>
> std::__1::allocator<std::__1::pair<const int, Templ8<int>::Member<br>
> *>>>'<br>
> typename map<K,Member*>::iterator it;<br>
> ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~<br>
> /usr/bin/../lib/c++/v1/type_traits:1184:57: note: in instantiation of<br>
> member class 'Templ8<int>::Member' requested here<br>
> decltype((_VSTD::declval<_Tp>() = _VSTD::declval<_Arg>(), true_type()))<br>
> ^<br>
> /usr/bin/../lib/c++/v1/type_traits:1186:1: note: while substituting<br>
> deduced template arguments into function template<br>
> '__is_assignable_test' [with _Tp = Templ8<int>::Member *&, _Arg = <no<br>
> value>]<br>
> __is_assignable_test(_Tp&&, _Arg&&);<br>
> ^<br>
> /usr/bin/../lib/c++/v1/type_traits:1214:14: note: in instantiation of<br>
> template class 'std::__1::__is_assignable_imp<Templ8<int>::Member *&,<br>
> Templ8<int>::Member *&, false>' requested here<br>
> : public __is_assignable_imp<_Tp, _Arg> {};<br>
> ^<br>
> /usr/bin/../lib/c++/v1/type_traits:2616:38: note: in instantiation of<br>
> template class 'std::__1::is_assignable<Templ8<int>::Member *&,<br>
> Templ8<int>::Member *&>' requested here<br>
> : public __is_nothrow_assignable<is_assignable<_Tp, _Arg>::value,<br>
> _Tp, _Arg><br>
> ^<br>
> /usr/bin/../lib/c++/v1/type_traits:2667:14: note: in instantiation of<br>
> template class 'std::__1::is_nothrow_assignable<Templ8<int>::Member<br>
> *&, Templ8<int>::Member *&>' requested here<br>
> : public is_nothrow_assignable<typename add_lvalue_reference<_Tp>::type,<br>
> ^<br>
> /usr/bin/../lib/c++/v1/utility:250:20: note: (skipping 9 contexts in<br>
> backtrace; use -ftemplate-backtrace-limit=0 to see all)<br>
> is_nothrow_copy_assignable<second_type>::value)<br>
> ^<br>
> /usr/bin/../lib/c++/v1/__config:253:34: note: expanded from macro '_NOEXCEPT_'<br>
> # define _NOEXCEPT_(x) noexcept(x)<br>
> ^<br>
> /usr/bin/../lib/c++/v1/memory:2386:15: note: in instantiation of<br>
> template class 'std::__1::__libcpp_compressed_pair_imp<std::__1::__tree_end_node<std::__1::__tree_node_base<void<br>
> *> *>,<br>
> std::__1::allocator<std::__1::__tree_node<std::__1::pair<int,<br>
> Templ8<int>::Member *>, void *>>, 2>' requested here<br>
> : private __libcpp_compressed_pair_imp<_T1, _T2><br>
> ^<br>
> /usr/bin/../lib/c++/v1/__tree:813:56: note: in instantiation of<br>
> template class 'std::__1::__compressed_pair<std::__1::__tree_end_node<std::__1::__tree_node_base<void<br>
> *> *>,<br>
> std::__1::allocator<std::__1::__tree_node<std::__1::pair<int,<br>
> Templ8<int>::Member *>, void *>>>' requested here<br>
> __compressed_pair<__end_node_t, __node_allocator> __pair1_;<br>
> ^<br>
> /usr/bin/../lib/c++/v1/map:711:22: note: in instantiation of template<br>
> class 'std::__1::__tree<std::__1::pair<int, Templ8<int>::Member *>,<br>
> std::__1::__map_value_compare<int, Templ8<int>::Member *,<br>
> std::__1::less<int>, true>,<br>
> std::__1::allocator<std::__1::pair<int, Templ8<int>::Member *>>>'<br>
> requested here<br>
> typedef typename __base::__node_traits __node_traits;<br>
> ^<br>
> main_bug.cpp:9:22: note: in instantiation of template class<br>
> 'std::__1::map<int, Templ8<int>::Member *, std::__1::less<int>,<br>
> std::__1::allocator<std::__1::pair<const int, Templ8<int>::Member<br>
> *>>>'<br>
> requested here<br>
> typedef typename map<K,Member*>::iterator iterator_type;<br>
> ^<br>
> main_bug.cpp:13:17: note: in instantiation of template class<br>
> 'Templ8<int>' requested here<br>
> Templ8<int> test;<br>
> ^<br>
> 1 error generated.<br>
> _______________________________________________<br>
> LLVM Developers mailing list<br>
> <a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</div></div></blockquote></div><br></div>