Created attachment 34740 [details] class description employing layered string- and int-indexed maps-within-maps Attached is modulecache.hh, part of Xiphos, which was recently involved in a Fedora gcc5 mass rebuild test for upcoming Fedora 22. This file exhibits a template complaint regarding nested std::map usage. The nesting provides an intuitive access to data content by allowing subscripting at any map level to obtain all subordinate content. The plain fact is that this code has been compiling in gcc4 since approximately 2008. It was then found that using -ftemplate-depth=128 makes the gcc5 compilation survive, but I don't see why this should be necessary, considering that the code has been fine for 7 years preceding, without use of any such modifiers. Has the default depth limit changed in gcc5? FYI recommended to file this report by an involved Fedora engineer; I am Xiphos project admin. In file included from /usr/include/c++/5.0.0/map:60:0, from ../src/main/modulecache.hh:45, from ../src/main/modulecache.cc:30: /usr/include/c++/5.0.0/bits/stl_tree.h: In instantiation of 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_destroy_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type) [with _Key = int; _Val = std::pair<const int, ModuleCache::CacheVerse>; _KeyOfValue = std::_Select1st<std::pair<const int, ModuleCache::CacheVerse> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, ModuleCache::CacheVerse> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, ModuleCache::CacheVerse> >*]': /usr/include/c++/5.0.0/bits/stl_tree.h:562:17: required from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_drop_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type) [with _Key = int; _Val = std::pair<const int, ModuleCache::CacheVerse>; _KeyOfValue = std::_Select1st<std::pair<const int, ModuleCache::CacheVerse> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, ModuleCache::CacheVerse> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, ModuleCache::CacheVerse> >*]' /usr/include/c++/5.0.0/bits/stl_tree.h:1493:16: required from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_erase(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type) [with _Key = int; _Val = std::pair<const int, ModuleCache::CacheVerse>; _KeyOfValue = std::_Select1st<std::pair<const int, ModuleCache::CacheVerse> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, ModuleCache::CacheVerse> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, ModuleCache::CacheVerse> >*]' /usr/include/c++/5.0.0/bits/stl_tree.h:859:17: required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::~_Rb_tree() [with _Key = int; _Val = std::pair<const int, ModuleCache::CacheVerse>; _KeyOfValue = std::_Select1st<std::pair<const int, ModuleCache::CacheVerse> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, ModuleCache::CacheVerse> >]' /usr/include/c++/5.0.0/bits/stl_map.h:96:11: required from 'void __gnu_cxx::new_allocator<_Tp>::destroy(__gnu_cxx::new_allocator<_Tp>::pointer) [with _Tp = std::pair<const int, std::map<int, ModuleCache::CacheVerse> >; __gnu_cxx::new_allocator<_Tp>::pointer = std::pair<const int, std::map<int, ModuleCache::CacheVerse> >*]' /usr/include/c++/5.0.0/bits/stl_tree.h:521:9: required from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_destroy_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type) [with _Key = int; _Val = std::pair<const int, std::map<int, ModuleCache::CacheVerse> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::map<int, ModuleCache::CacheVerse> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::map<int, ModuleCache::CacheVerse> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, std::map<int, ModuleCache::CacheVerse> > >*]' /usr/include/c++/5.0.0/bits/stl_tree.h:562:17: [ skipping 14 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ] /usr/include/c++/5.0.0/bits/stl_tree.h:521:9: required from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_destroy_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type) [with _Key = const std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > >; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >*]' /usr/include/c++/5.0.0/bits/stl_tree.h:562:17: required from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_drop_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type) [with _Key = const std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > >; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >*]' /usr/include/c++/5.0.0/bits/stl_tree.h:1493:16: required from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_erase(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type) [with _Key = const std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > >; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >*]' /usr/include/c++/5.0.0/bits/stl_tree.h:859:17: required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::~_Rb_tree() [with _Key = const std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > >; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >]' /usr/include/c++/5.0.0/bits/stl_map.h:163:14: required from 'std::map<_Key, _Tp, _Compare, _Alloc>::map() [with _Key = const std::basic_string<char>; _Tp = std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > >; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::map<int, std::map<int, std::map<int, std::map<int, ModuleCache::CacheVerse> > > > > >]' ../src/main/modulecache.cc:34:23: required from here /usr/include/c++/5.0.0/bits/stl_tree.h:521:22: fatal error: template instantiation depth exceeds maximum of 25 (use -ftemplate-depth= to increase the maximum) { get_allocator().destroy(__p->_M_valptr()); } ^
Please provide preprocessed source (see http://gcc.gnu.org/bugs/ for details how).
Created attachment 34741 [details] preprocessed file
Note that the package explicitly uses -ftemplate-depth=25 (without that the .ii files compiles fine). So maybe just some changes in libstdc++ that trigger the limit?
What command line options are used? With explicit -ftemplate-depth=25 (or even 27) it indeed fails, succeeds with 28, but the default is 900 AFAIK. Have those command line options changed in any way since the compilation with the older g++?
Verified that even with 2.5 years old cc1plus we still trigger the instantiation limit, so it indeed is some changes in libstdc++. Guess you can try -ftemplate-depth=20 etc. in 4.9 to see how close to the limit you were before.
Yeah, the default is 900. (C++11 recommends 1024 AFAIK.) From what I can see they used /usr/lib64/ccache/g++ -v -save-temps -g3 -O0 -DDEBUG -ftemplate-depth-25 -DHAVE_CONFIG_H -pthread -Idefault/src/main -I../src/main -Idefault -I.. -Idefault/src -I../src -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/gconf/2 -I/usr/include/libgsf-1 -I/usr/include/libglade-2.0 -I/usr/include/webkitgtk-1.0 -I/usr/include/libsoup-2.4 -I/usr/include/libxml2 -I/usr/include/gtk-2.0 -I/usr/lib64/gtk-2.0/include -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/libdrm -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/sword -I/usr/include/biblesync/bibleysnc -I/usr/include/uuid ../src/main/modulecache.cc -c -o default/src/main/modulecache_1.o I don't know if those command-line options have changed.
Trying to use the standard library with such a tiny limit is simply not going to work. If it worked previously you got lucky, but if you need to raise the limit now then that's what you need to do. What's the purpose of enforcing such a tiny limit anyway?
As I said, it's not reasonable to use libstdc++ with such tiny limits. (In reply to Jonathan Wakely from comment #7) > What's the purpose of enforcing such a tiny limit anyway? Changing status to WAITING, and the bug will be closed if no answer is forthcoming.