https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61836

            Bug ID: 61836
           Summary: Incorrect template argument deduction/substitution
                    failure?
           Product: gcc
           Version: 4.9.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ilja.j.honkonen at nasa dot gov

Created attachment 33137
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33137&action=edit
Preprocessed source

Trying to enable_if a particular implementation of a class member function
based on its template argument:

template<
    class Out_T
> typename std::enable_if<
    std::is_same<Out_T, bool>::value,
    Out_T
>::type get_parsed_value(...)

template<
    class Out_T
> typename std::enable_if<
    std::is_same<Out_T, double>::value,
    Out_T
>::type get_parsed_value(...)


including std::array and Eigen::Matrix:

template<class T> struct is_std_array_double : std::false_type {};
template<size_t N> struct is_std_array_double<
    std::array<double, N>
> : std::true_type {};


template<class T> struct is_eigen_vector_double : std::false_type {};
template<size_t N> struct is_eigen_vector_double<
    Eigen::Matrix<double, N, 1>
> : std::true_type {};


template<
    class Out_T
> typename std::enable_if<
    detail::is_std_array_double<Out_T>::value,
    Out_T
>::type get_parsed_value(...)

template<
    class Out_T
> typename std::enable_if<
    detail::is_eigen_vector_double<Out_T>::value,
    Out_T
>::type get_parsed_value(...)


fails because apparently is_eigen_vector_double returns false for
Eigen::Matrix<double, N, 1> even though it shouldn't. The same code compiles
with clangs 3.3-5.


Compile command:
/opt/local/gcc-4.9.1/bin/g++ -I source -std=c++11 -W -Wall -Wextra -pedantic
-O3  -I /opt/local/include/eigen3 -I /opt/local/include -L /opt/local/lib
-lboost_coroutine-mt -lboost_system-mt -lboost_random-mt
-lboost_program_options-mt -I /Users/iljah/include -L /Users/iljah/lib
-lmuparserx -I /Users/iljah/include
tests/program_options/variable_to_option.cpp -o
tests/program_options/variable_to_option.exe -Wno-unused-local-typedefs
-save-temps -v


Output:
Using built-in specs.
COLLECT_GCC=/opt/local/gcc-4.9.1/bin/g++
COLLECT_LTO_WRAPPER=/opt/local/gcc-4.9.1/libexec/gcc/x86_64-apple-darwin13.3.0/4.9.1/lto-wrapper
Target: x86_64-apple-darwin13.3.0
Configured with: ../gcc-4.9.1/configure --prefix=/opt/local/gcc-4.9.1
--enable-shared --enable-threads=posix --enable-__cxa_atexit --disable-multilib
--with-system-zlib --enable-languages=c,c++ --with-gmp=/opt/local
--with-mpfr=/opt/local --with-mpc=/opt/local --disable-bootstrap
Thread model: posix
gcc version 4.9.1 (GCC) 
COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.9.3' '-I' 'source' '-std=c++11'
'-Wall' '-Wextra' '-Wpedantic' '-O3' '-I' '/opt/local/include/eigen3' '-I'
'/opt/local/include' '-L/opt/local/lib' '-I' '/Users/iljah/include'
'-L/Users/iljah/lib' '-I' '/Users/iljah/include' '-o'
'tests/program_options/variable_to_option.exe' '-Wno-unused-local-typedefs'
'-save-temps' '-v' '-shared-libgcc' '-mtune=core2'
 /opt/local/gcc-4.9.1/libexec/gcc/x86_64-apple-darwin13.3.0/4.9.1/cc1plus -E
-quiet -v -I source -I /opt/local/include/eigen3 -I /opt/local/include -I
/Users/iljah/include -I /Users/iljah/include -D__DYNAMIC__
tests/program_options/variable_to_option.cpp -fPIC -mmacosx-version-min=10.9.3
-mtune=core2 -std=c++11 -Wall -Wextra -Wpedantic -Wno-unused-local-typedefs -O3
-fpch-preprocess -o variable_to_option.ii
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory
"/opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/../../../../x86_64-apple-darwin13.3.0/include"
ignoring duplicate directory "/Users/iljah/include"
#include "..." search starts here:
#include <...> search starts here:
 source
 /opt/local/include/eigen3
 /opt/local/include
 /Users/iljah/include

/opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/../../../../include/c++/4.9.1

/opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/../../../../include/c++/4.9.1/x86_64-apple-darwin13.3.0

/opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/../../../../include/c++/4.9.1/backward
 /opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/include
 /opt/local/gcc-4.9.1/include
 /opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/include-fixed
 /usr/include
 /System/Library/Frameworks
 /Library/Frameworks
End of search list.
COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.9.3' '-I' 'source' '-std=c++11'
'-Wall' '-Wextra' '-Wpedantic' '-O3' '-I' '/opt/local/include/eigen3' '-I'
'/opt/local/include' '-L/opt/local/lib' '-I' '/Users/iljah/include'
'-L/Users/iljah/lib' '-I' '/Users/iljah/include' '-o'
'tests/program_options/variable_to_option.exe' '-Wno-unused-local-typedefs'
'-save-temps' '-v' '-shared-libgcc' '-mtune=core2'
 /opt/local/gcc-4.9.1/libexec/gcc/x86_64-apple-darwin13.3.0/4.9.1/cc1plus
-fpreprocessed variable_to_option.ii -fPIC -quiet -dumpbase
variable_to_option.cpp -mmacosx-version-min=10.9.3 -mtune=core2 -auxbase
variable_to_option -O3 -Wall -Wextra -Wpedantic -Wno-unused-local-typedefs
-std=c++11 -version -o variable_to_option.s
GNU C++ (GCC) version 4.9.1 (x86_64-apple-darwin13.3.0)
    compiled by GNU C version 4.8.2, GMP version 6.0.0, MPFR version 3.1.1-p2,
MPC version 1.0.2
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++ (GCC) version 4.9.1 (x86_64-apple-darwin13.3.0)
    compiled by GNU C version 4.8.2, GMP version 6.0.0, MPFR version 3.1.1-p2,
MPC version 1.0.2
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: bd2008a6eb882424f30fe6b02f71d084
In file included from tests/program_options/variable_to_option.cpp:41:0:
source/boundaries/variable_to_option.hpp: In instantiation of ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’:
tests/program_options/variable_to_option.cpp:135:57:   required from here
source/boundaries/variable_to_option.hpp:366:13: error: no matching function
for call to
‘pamhd::boundaries::Variable_To_Option<Momentum_Density>::get_parsed_value(const
std::array<double, 3ul>&)’
   >(position);
             ^
source/boundaries/variable_to_option.hpp:366:13: note: candidates are:
source/boundaries/variable_to_option.hpp:408:10: note: template<class Out_T>
typename std::enable_if<std::is_same<Out_T, bool>::value, Out_T>::type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const
std::array<double, 3ul>&) [with Out_T = Out_T; Last_Variable =
Momentum_Density]
  >::type get_parsed_value(const std::array<double, 3>& position)
          ^
source/boundaries/variable_to_option.hpp:408:10: note:   template argument
deduction/substitution failed:
source/boundaries/variable_to_option.hpp: In substitution of ‘template<class
Out_T> typename std::enable_if<std::is_same<Out_T, bool>::value, Out_T>::type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const
std::array<double, 3ul>&) [with Out_T = Eigen::Matrix<double, 3, 1>]’:
source/boundaries/variable_to_option.hpp:366:13:   required from ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’
tests/program_options/variable_to_option.cpp:135:57:   required from here
source/boundaries/variable_to_option.hpp:408:10: error: no type named ‘type’ in
‘struct std::enable_if<false, Eigen::Matrix<double, 3, 1> >’
source/boundaries/variable_to_option.hpp: In instantiation of ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’:
tests/program_options/variable_to_option.cpp:135:57:   required from here
source/boundaries/variable_to_option.hpp:430:10: note: template<class Out_T>
typename std::enable_if<std::is_same<Out_T, int>::value, Out_T>::type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const
std::array<double, 3ul>&) [with Out_T = Out_T; Last_Variable =
Momentum_Density]
  >::type get_parsed_value(const std::array<double, 3>& position)
          ^
source/boundaries/variable_to_option.hpp:430:10: note:   template argument
deduction/substitution failed:
source/boundaries/variable_to_option.hpp: In substitution of ‘template<class
Out_T> typename std::enable_if<std::is_same<Out_T, int>::value, Out_T>::type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const
std::array<double, 3ul>&) [with Out_T = Eigen::Matrix<double, 3, 1>]’:
source/boundaries/variable_to_option.hpp:366:13:   required from ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’
tests/program_options/variable_to_option.cpp:135:57:   required from here
source/boundaries/variable_to_option.hpp:430:10: error: no type named ‘type’ in
‘struct std::enable_if<false, Eigen::Matrix<double, 3, 1> >’
source/boundaries/variable_to_option.hpp: In instantiation of ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’:
tests/program_options/variable_to_option.cpp:135:57:   required from here
source/boundaries/variable_to_option.hpp:452:10: note: template<class Out_T>
typename std::enable_if<std::is_same<Out_T, double>::value, Out_T>::type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const
std::array<double, 3ul>&) [with Out_T = Out_T; Last_Variable =
Momentum_Density]
  >::type get_parsed_value(const std::array<double, 3>& position)
          ^
source/boundaries/variable_to_option.hpp:452:10: note:   template argument
deduction/substitution failed:
source/boundaries/variable_to_option.hpp: In substitution of ‘template<class
Out_T> typename std::enable_if<std::is_same<Out_T, double>::value, Out_T>::type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const
std::array<double, 3ul>&) [with Out_T = Eigen::Matrix<double, 3, 1>]’:
source/boundaries/variable_to_option.hpp:366:13:   required from ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’
tests/program_options/variable_to_option.cpp:135:57:   required from here
source/boundaries/variable_to_option.hpp:452:10: error: no type named ‘type’ in
‘struct std::enable_if<false, Eigen::Matrix<double, 3, 1> >’
source/boundaries/variable_to_option.hpp: In instantiation of ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’:
tests/program_options/variable_to_option.cpp:135:57:   required from here
source/boundaries/variable_to_option.hpp:474:10: note: template<class Out_T>
typename
std::enable_if<pamhd::boundaries::detail::is_std_array_double<Out_T>::value,
Out_T>::type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const
std::array<double, 3ul>&) [with Out_T = Out_T; Last_Variable =
Momentum_Density]
  >::type get_parsed_value(const std::array<double, 3>& position)
          ^
source/boundaries/variable_to_option.hpp:474:10: note:   template argument
deduction/substitution failed:
source/boundaries/variable_to_option.hpp: In substitution of ‘template<class
Out_T> typename
std::enable_if<pamhd::boundaries::detail::is_std_array_double<Out_T>::value,
Out_T>::type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const
std::array<double, 3ul>&) [with Out_T = Eigen::Matrix<double, 3, 1>]’:
source/boundaries/variable_to_option.hpp:366:13:   required from ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’
tests/program_options/variable_to_option.cpp:135:57:   required from here
source/boundaries/variable_to_option.hpp:474:10: error: no type named ‘type’ in
‘struct std::enable_if<false, Eigen::Matrix<double, 3, 1> >’
source/boundaries/variable_to_option.hpp: In instantiation of ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’:
tests/program_options/variable_to_option.cpp:135:57:   required from here
source/boundaries/variable_to_option.hpp:529:10: note: template<class Out_T>
typename
std::enable_if<pamhd::boundaries::detail::is_eigen_vector_double<Out_T>::value,
Out_T>::type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const
std::array<double, 3ul>&) [with Out_T = Out_T; Last_Variable =
Momentum_Density]
  >::type get_parsed_value(const std::array<double, 3>& position)
          ^
source/boundaries/variable_to_option.hpp:529:10: note:   template argument
deduction/substitution failed:
source/boundaries/variable_to_option.hpp: In substitution of ‘template<class
Out_T> typename
std::enable_if<pamhd::boundaries::detail::is_eigen_vector_double<Out_T>::value,
Out_T>::type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const
std::array<double, 3ul>&) [with Out_T = Eigen::Matrix<double, 3, 1>]’:
source/boundaries/variable_to_option.hpp:366:13:   required from ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’
tests/program_options/variable_to_option.cpp:135:57:   required from here
source/boundaries/variable_to_option.hpp:529:10: error: no type named ‘type’ in
‘struct std::enable_if<false, Eigen::Matrix<double, 3, 1> >’
source/boundaries/variable_to_option.hpp: In member function ‘typename
Last_Variable::data_type
pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const
Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable =
Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3,
1>]’:
source/boundaries/variable_to_option.hpp:367:2: warning: control reaches end of
non-void function [-Wreturn-type]
  }
  ^

Reply via email to