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