Bug 1464612 - gcc 7.1.1 cannot compile recent octave code
Summary: gcc 7.1.1 cannot compile recent octave code
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: 26
Hardware: x86_64
OS: Linux
unspecified
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2017-06-23 23:03 UTC by Dmitri A. Sergatskov
Modified: 2017-07-20 08:06 UTC (History)
8 users (show)

Fixed In Version: gcc-7.1.1-4.fc26
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2017-07-20 08:06:54 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
failing symtab.cc file (54.94 KB, text/x-csrc)
2017-06-23 23:06 UTC, Dmitri A. Sergatskov
no flags Details
symtab.ii (2.81 MB, text/plain)
2017-06-24 12:19 UTC, Dmitri A. Sergatskov
no flags Details


Links
System ID Private Priority Status Summary Last Updated
GNU Compiler Collection 81215 0 None None None 2017-06-26 18:34:59 UTC

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.


Note You need to log in before you can comment on or make changes to this bug.