Description of problem: compiling a recent (4.3.0+) version of octave fails with g++ (7.1.1-2 and -3) Version-Release number of selected component (if applicable): 7.1.1-2 and -3 How reproducible: 100% Steps to Reproduce: 1. get octave dev code (see www.octave.com for details). 2 bootstrap, 3 configure, 3 make Actual results: Compile fails with: libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -Iliboctave -I../liboctave -I../liboctave/array -Iliboctave/numeric -I../liboctave/numeric -Iliboctave/operators -I../liboctave/operators -I../liboctave/system -I../liboctave/util -I../libinterp/octave-value -Ilibinterp -I../libinterp -I../libinterp/operators -Ilibinterp/parse-tree -I../libinterp/parse-tree -Ilibinterp/corefcn -I../libinterp/corefcn -I../liboctave/wrappers -I/usr/include/GraphicsMagick -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/freetype2 -I/usr/include/libpng16 -fPIC -pthread -fopenmp -Wall -W -Wshadow -Wold-style-cast -Wformat -Wpointer-arith -Wwrite-strings -Wcast-align -Wcast-qual -O2 -std=c++11 -MT libinterp/corefcn/libinterp_corefcn_libcorefcn_la-symtab.lo -MD -MP -MF libinterp/corefcn/.deps/libinterp_corefcn_libcorefcn_la-symtab.Tpo -c ../libinterp/corefcn/symtab.cc -fPIC -DPIC -o libinterp/corefcn/.libs/libinterp_corefcn_libcorefcn_la-symtab.o ../libinterp/corefcn/symtab.cc: In member function ‘octave_value symbol_table::dump() const’: ../libinterp/corefcn/symtab.cc:1446:73: error: no matching function for call to ‘dump_container_map(const std::map<std::__cxx11::basic_string<char>, std::set<std::__cxx11::basic_string<char> > >&)’ {"precedence_table", dump_container_map (m_class_precedence_table)}, ^ ../libinterp/corefcn/symtab.cc:1424:1: note: candidate: template<class V, template<class ...> class C> octave_value dump_container_map(const std::map<std::__cxx11::basic_string<char>, C<V> >&) dump_container_map (const std::map<std::string, C<V>>& container_map) ^~~~~~~~~~~~~~~~~~ ../libinterp/corefcn/symtab.cc:1424:1: note: template argument deduction/substitution failed: ../libinterp/corefcn/symtab.cc:1446:73: note: candidate expects 1 argument, 3 provided {"precedence_table", dump_container_map (m_class_precedence_table)}, ^ ../libinterp/corefcn/symtab.cc:1447:59: error: no matching function for call to ‘dump_container_map(const std::map<std::__cxx11::basic_string<char>, std::__cxx11::list<std::__cxx11::basic_string<char> > >&)’ {"parent_classes", dump_container_map (m_parent_map)}}; ^ ../libinterp/corefcn/symtab.cc:1424:1: note: candidate: template<class V, template<class ...> class C> octave_value dump_container_map(const std::map<std::__cxx11::basic_string<char>, C<V> >&) dump_container_map (const std::map<std::string, C<V>>& container_map) ^~~~~~~~~~~~~~~~~~ ../libinterp/corefcn/symtab.cc:1424:1: note: template argument deduction/substitution failed: ../libinterp/corefcn/symtab.cc:1447:59: note: candidate expects 1 argument, 2 provided {"parent_classes", dump_container_map (m_parent_map)}}; ^ ../libinterp/corefcn/symtab.cc:1447:61: error: could not convert ‘{{"function_info", symbol_table::dump_fcn_table_map() const()}, {"precedence_table", <expression error>}, {"parent_classes", <expression error>}}’ from ‘<brace-enclosed initializer list>’ to ‘std::map<std::__cxx11::basic_string<char>, octave_value>’ {"parent_classes", dump_container_map (m_parent_map)}}; ^ make[2]: *** [Makefile:18264: libinterp/corefcn/libinterp_corefcn_libcorefcn_la-symtab.lo] Error 1 Expected results: compile succeeds Additional info: Code compiled fine with clang (4.0.0 on Fedora 26, RH 7.3 with gcc 4.8.5) other systems. See e.g.: http://buildbot.octave.org:8010/waterfall (all fedora built are run on Fedora 26) Dmitri.
Created attachment 1291287 [details] failing symtab.cc file
Setting CXXFLAGS to "-std=c++1z" allows compile to finish successfully. with either "-std=c++11" or "-std=c++14" it fails. Though this provides a workaround the problem is still there. Dmitri.
(In reply to Dmitri A. Sergatskov from comment #1) > Created attachment 1291287 [details] > failing symtab.cc file symtab.cc is not really useful, can you please attach preprocessed source (e.g. add -save-temps to the above command and attach symtab.ii)? Thanks.
Created attachment 1291482 [details] symtab.ii
See also: http://lists.gnu.org/archive/html/octave-maintainers/2017-06/msg00117.html
I believe this has changed with http://gcc.gnu.org/PR42329 , at least the preprocessed source started to ICE with http://gcc.gnu.org/r243870 and no longer ICEs, but rejects the testcase starting with http://gcc.gnu.org/r243890 . I believe this is when trying to unify the Container template template param of template<typename T> template<template <typename...> class Container> Array<T>::Array (const Container<T>& a, const dim_vector& dv) : dimensions (dv), rep (new typename Array<T>::ArrayRep (dv.safe_numel ())), slice_data (rep->data), slice_len (rep->len) Whether G++ is correct on this octave testcase or not I'd like to defer to our C++ folks.
Sorry, the above Array ctor is just the first spot where the template template param unification does something. Somewhat reduced testcase that also was accepted in r243869 and is rejected in r243890 is: #include <string> #include <map> #include <set> template <typename V, template <typename...> class C> void bar (const std::map<std::string, C<V>>& x) { } void foo (std::map<std::string, std::set<std::string>> &x) { bar (x); }
Note ICC 17 rejects it too.
Wonder if this isn't because std::set template actually doesn't have one template argument, but 3, and std::list doesn't have one template argument, but 2.
#include <string> #include <list> #include <map> #include <set> template <typename V, typename... W, template <typename...> class C> void bar (const std::map<std::string, C<V, W...>>& x) { } void foo (std::map<std::string, std::set<std::string>>& x, std::map<std::string, std::list<std::string>>& y) { bar (x); bar (y); } works with both g++ 6 and g++ 7, so perhaps you should just add the parameter pack to dump_container_map. Either: @@ -99784,9 +99784,9 @@ symbol_table::find_submethod (const std: return fcn; } -template <typename V, template <typename...> class C> +template <typename V, typename... W, template <typename...> class C> static octave_value -dump_container_map (const std::map<std::string, C<V>>& container_map) +dump_container_map (const std::map<std::string, C<V, W...>>& container_map) { if (container_map.empty ()) return octave_value (Matrix ()); @@ -99796,7 +99796,7 @@ dump_container_map (const std::map<std:: for (const auto& nm_container : container_map) { std::string nm = nm_container.first; - const C<V>& container = nm_container.second; + const C<V, W...>& container = nm_container.second; info_map[nm] = Cell (container); } or template <typename... V, template <typename...> class C> static octave_value dump_container_map (const std::map<std::string, C<V...>>& container_map) { ... const C<V...>& container = nm_container.second; ... }
Reduced further: template<typename U> struct X { }; template<typename T, typename U = void> struct set { }; template <typename V, template <typename...> class C> void bar (const X<C<V>>&) { } void foo (X<set<int>>& x) { bar (x); }
The octave's code has been changed. See: http://octave.1599824.n4.nabble.com/gcc7-build-error-with-recent-tip-tp4683876p4683911.html and http://hg.savannah.gnu.org/hgweb/octave/rev/93371ce5378d But the question remains if this is a bug in g++ or not. Dmitri.
Looks like a bug, yes.
Fixed upstream.
Should be fixed in gcc-7.1.1-4.fc{26,27} and above.