Bug 1464612

Summary: gcc 7.1.1 cannot compile recent octave code
Product: [Fedora] Fedora Reporter: Dmitri A. Sergatskov <dasergatskov>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 26CC: dasergatskov, davejohansen, fweimer, jakub, jason, jwakely, law, mpolacek
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: gcc-7.1.1-4.fc26 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-07-20 08:06:54 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
failing symtab.cc file
none
symtab.ii none

Description Dmitri A. Sergatskov 2017-06-23 23:03:23 UTC
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.

Comment 1 Dmitri A. Sergatskov 2017-06-23 23:06:25 UTC
Created attachment 1291287 [details]
failing symtab.cc file

Comment 2 Dmitri A. Sergatskov 2017-06-23 23:11:35 UTC
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.

Comment 3 Jakub Jelinek 2017-06-24 06:47:13 UTC
(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.

Comment 4 Dmitri A. Sergatskov 2017-06-24 12:19:37 UTC
Created attachment 1291482 [details]
symtab.ii

Comment 5 Dmitri A. Sergatskov 2017-06-24 16:53:39 UTC
See also:

http://lists.gnu.org/archive/html/octave-maintainers/2017-06/msg00117.html

Comment 6 Jakub Jelinek 2017-06-26 08:47:18 UTC
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.

Comment 7 Jakub Jelinek 2017-06-26 09:05:27 UTC
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);
}

Comment 8 Jakub Jelinek 2017-06-26 09:10:02 UTC
Note ICC 17 rejects it too.

Comment 9 Jakub Jelinek 2017-06-26 09:21:25 UTC
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.

Comment 10 Jakub Jelinek 2017-06-26 09:43:44 UTC
#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;
...
}

Comment 11 Jonathan Wakely 2017-06-26 11:46:12 UTC
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);
}

Comment 12 Dmitri A. Sergatskov 2017-06-26 12:44:43 UTC
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.

Comment 13 Jason Merrill 2017-06-26 15:56:45 UTC
Looks like a bug, yes.

Comment 14 Jason Merrill 2017-06-28 21:12:40 UTC
Fixed upstream.

Comment 15 Jakub Jelinek 2017-07-20 08:06:54 UTC
Should be fixed in gcc-7.1.1-4.fc{26,27} and above.