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

            Bug ID: 100630
           Summary: Unexpected implicit conversion from volatile bool& to
                    std::filesystem::path in gcc <= 10
           Product: gcc
           Version: 10.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: romain.geissler at amadeus dot com
  Target Milestone: ---

Hi,

I came across this issue today (which I think is unexpected) with gcc 8, 9 and
10. It seems that the following code triggers some implicit conversion from
volatile bool& to std::filesystem::path while this was definitely not the
intention:

#include <filesystem>
#include <iostream>

class Printer
{
    public:
        Printer& operator<<(bool iValue)
        {
            std::cout << __PRETTY_FUNCTION__<< ": " << std::boolalpha << iValue
<< std::endl;

            return *this;
        };

        Printer& operator<<(const std::filesystem::path& iPath)
        {
            std::cout << __PRETTY_FUNCTION__<< ": " << std::boolalpha << iPath
<< std::endl;

            return *this;
        };
};

int main()
{
    Printer aPrinter;
    volatile bool a = false;

    aPrinter << a;
};


It raises the following error (for example using gcc 10 in Compiler Explorer):

In file included from
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/filesystem:45,
                 from <source>:1:
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h: In
instantiation of 'struct
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>':
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:138:12:  
required from 'struct std::__and_<std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:143:12:  
required from 'struct std::__and_<std::__not_<std::is_same<bool,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:123:11:  
required by substitution of 'template<class _Tp1, class _Tp2> using _Path =
typename std::enable_if<std::__and_<std::__not_<std::is_same<typename
std::remove_cv< <template-parameter-1-1> >::type,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<typename
std::remove_pointer<_Tp>::type> >,
std::filesystem::__cxx11::__detail::__constructible_from<_Tp1, _Tp2> >::value,
std::filesystem::__cxx11::path>::type [with _Tp1 = volatile bool; _Tp2 = void]'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:223:7:  
required by substitution of 'template<class _Source, class _Require>
std::filesystem::__cxx11::path::path(const _Source&,
std::filesystem::__cxx11::path::format) [with _Source = volatile bool; _Require
= <missing>]'
<source>:27:17:   required from here
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:119:29:
error: no matching function for call to '__is_path_src(volatile bool, int)'
  119 |     : decltype(__is_path_src(std::declval<_Source>(), 0))
      |                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:95:5: note:
candidate: 'template<class _Iter>
std::filesystem::__cxx11::__detail::__is_path_iter_src<_Iter>
std::filesystem::__cxx11::__detail::__is_path_src(_Iter, int)'
   95 |     __is_path_src(_Iter, int);
      |     ^~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:95:5: note:
  template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h: In
substitution of 'template<class _Iter, class _Iter_traits> using
__is_path_iter_src = std::__and_<std::__or_<std::is_same<typename
std::remove_const<typename _Iter_traits::value_type>::type, char>,
std::is_same<typename std::remove_const<typename
_Iter_traits::value_type>::type, wchar_t>, std::is_same<typename
std::remove_const<typename _Iter_traits::value_type>::type, char16_t>,
std::is_same<typename std::remove_const<typename
_Iter_traits::value_type>::type, char32_t> >,
std::is_base_of<std::input_iterator_tag, typename
_Iter_traits::iterator_category> > [with _Iter = bool; _Iter_traits =
std::iterator_traits<bool>]':
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:95:5:  
required by substitution of 'template<class _Iter>
std::filesystem::__cxx11::__detail::__is_path_iter_src<_Iter>
std::filesystem::__cxx11::__detail::__is_path_src(_Iter, int) [with _Iter =
bool]'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:119:29:  
required from 'struct
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:138:12:  
required from 'struct std::__and_<std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:143:12:  
required from 'struct std::__and_<std::__not_<std::is_same<bool,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:123:11:  
required by substitution of 'template<class _Tp1, class _Tp2> using _Path =
typename std::enable_if<std::__and_<std::__not_<std::is_same<typename
std::remove_cv< <template-parameter-1-1> >::type,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<typename
std::remove_pointer<_Tp>::type> >,
std::filesystem::__cxx11::__detail::__constructible_from<_Tp1, _Tp2> >::value,
std::filesystem::__cxx11::path>::type [with _Tp1 = volatile bool; _Tp2 = void]'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:223:7:  
required by substitution of 'template<class _Source, class _Require>
std::filesystem::__cxx11::path::path(const _Source&,
std::filesystem::__cxx11::path::format) [with _Source = volatile bool; _Require
= <missing>]'
<source>:27:17:   required from here
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:88:11:
error: no type named 'value_type' in 'struct std::iterator_traits<bool>'
   88 |     using __is_path_iter_src
      |           ^~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h: In
instantiation of 'struct
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>':
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:138:12:  
required from 'struct std::__and_<std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:143:12:  
required from 'struct std::__and_<std::__not_<std::is_same<bool,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:123:11:  
required by substitution of 'template<class _Tp1, class _Tp2> using _Path =
typename std::enable_if<std::__and_<std::__not_<std::is_same<typename
std::remove_cv< <template-parameter-1-1> >::type,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<typename
std::remove_pointer<_Tp>::type> >,
std::filesystem::__cxx11::__detail::__constructible_from<_Tp1, _Tp2> >::value,
std::filesystem::__cxx11::path>::type [with _Tp1 = volatile bool; _Tp2 = void]'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:223:7:  
required by substitution of 'template<class _Source, class _Require>
std::filesystem::__cxx11::path::path(const _Source&,
std::filesystem::__cxx11::path::format) [with _Source = volatile bool; _Require
= <missing>]'
<source>:27:17:   required from here
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:99:5: note:
candidate: 'template<class _CharT, class _Traits, class _Alloc>
std::filesystem::__cxx11::__detail::__is_encoded_char<_CharT>
std::filesystem::__cxx11::__detail::__is_path_src(const
std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&, int)'
   99 |     __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int);
      |     ^~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:99:5: note:
  template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:119:29:
note:   mismatched types 'const std::__cxx11::basic_string<_CharT, _Traits,
_Allocator>' and 'volatile bool'
  119 |     : decltype(__is_path_src(std::declval<_Source>(), 0))
      |                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:103:5:
note: candidate: 'template<class _CharT, class _Traits>
std::filesystem::__cxx11::__detail::__is_encoded_char<_CharT>
std::filesystem::__cxx11::__detail::__is_path_src(const
std::basic_string_view<_CharT, _Traits>&, int)'
  103 |     __is_path_src(const basic_string_view<_CharT, _Traits>&, int);
      |     ^~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:103:5:
note:   template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:119:29:
note:   mismatched types 'const std::basic_string_view<_CharT, _Traits>' and
'volatile bool'
  119 |     : decltype(__is_path_src(std::declval<_Source>(), 0))
      |                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:107:5:
note: candidate: 'std::false_type
std::filesystem::__cxx11::__detail::__is_path_src(const _Unknown&, ...) [with
_Unknown = volatile bool; std::false_type = std::integral_constant<bool,
false>]' (near match)
  107 |     __is_path_src(const _Unknown&, ...);
      |     ^~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:107:5:
note:   conversion of argument 1 would be ill-formed:
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:119:29:
error: cannot bind non-const lvalue reference of type 'const volatile bool&' to
an rvalue of type 'volatile bool'
  119 |     : decltype(__is_path_src(std::declval<_Source>(), 0))
      |                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
ASM generation compiler returned: 1
In file included from
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/filesystem:45,
                 from <source>:1:
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h: In
instantiation of 'struct
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>':
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:138:12:  
required from 'struct std::__and_<std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:143:12:  
required from 'struct std::__and_<std::__not_<std::is_same<bool,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:123:11:  
required by substitution of 'template<class _Tp1, class _Tp2> using _Path =
typename std::enable_if<std::__and_<std::__not_<std::is_same<typename
std::remove_cv< <template-parameter-1-1> >::type,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<typename
std::remove_pointer<_Tp>::type> >,
std::filesystem::__cxx11::__detail::__constructible_from<_Tp1, _Tp2> >::value,
std::filesystem::__cxx11::path>::type [with _Tp1 = volatile bool; _Tp2 = void]'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:223:7:  
required by substitution of 'template<class _Source, class _Require>
std::filesystem::__cxx11::path::path(const _Source&,
std::filesystem::__cxx11::path::format) [with _Source = volatile bool; _Require
= <missing>]'
<source>:27:17:   required from here
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:119:29:
error: no matching function for call to '__is_path_src(volatile bool, int)'
  119 |     : decltype(__is_path_src(std::declval<_Source>(), 0))
      |                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:95:5: note:
candidate: 'template<class _Iter>
std::filesystem::__cxx11::__detail::__is_path_iter_src<_Iter>
std::filesystem::__cxx11::__detail::__is_path_src(_Iter, int)'
   95 |     __is_path_src(_Iter, int);
      |     ^~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:95:5: note:
  template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h: In
substitution of 'template<class _Iter, class _Iter_traits> using
__is_path_iter_src = std::__and_<std::__or_<std::is_same<typename
std::remove_const<typename _Iter_traits::value_type>::type, char>,
std::is_same<typename std::remove_const<typename
_Iter_traits::value_type>::type, wchar_t>, std::is_same<typename
std::remove_const<typename _Iter_traits::value_type>::type, char16_t>,
std::is_same<typename std::remove_const<typename
_Iter_traits::value_type>::type, char32_t> >,
std::is_base_of<std::input_iterator_tag, typename
_Iter_traits::iterator_category> > [with _Iter = bool; _Iter_traits =
std::iterator_traits<bool>]':
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:95:5:  
required by substitution of 'template<class _Iter>
std::filesystem::__cxx11::__detail::__is_path_iter_src<_Iter>
std::filesystem::__cxx11::__detail::__is_path_src(_Iter, int) [with _Iter =
bool]'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:119:29:  
required from 'struct
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:138:12:  
required from 'struct std::__and_<std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:143:12:  
required from 'struct std::__and_<std::__not_<std::is_same<bool,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:123:11:  
required by substitution of 'template<class _Tp1, class _Tp2> using _Path =
typename std::enable_if<std::__and_<std::__not_<std::is_same<typename
std::remove_cv< <template-parameter-1-1> >::type,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<typename
std::remove_pointer<_Tp>::type> >,
std::filesystem::__cxx11::__detail::__constructible_from<_Tp1, _Tp2> >::value,
std::filesystem::__cxx11::path>::type [with _Tp1 = volatile bool; _Tp2 = void]'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:223:7:  
required by substitution of 'template<class _Source, class _Require>
std::filesystem::__cxx11::path::path(const _Source&,
std::filesystem::__cxx11::path::format) [with _Source = volatile bool; _Require
= <missing>]'
<source>:27:17:   required from here
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:88:11:
error: no type named 'value_type' in 'struct std::iterator_traits<bool>'
   88 |     using __is_path_iter_src
      |           ^~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h: In
instantiation of 'struct
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>':
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:138:12:  
required from 'struct std::__and_<std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/type_traits:143:12:  
required from 'struct std::__and_<std::__not_<std::is_same<bool,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<volatile bool> >,
std::filesystem::__cxx11::__detail::__constructible_from<volatile bool, void>
>'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:123:11:  
required by substitution of 'template<class _Tp1, class _Tp2> using _Path =
typename std::enable_if<std::__and_<std::__not_<std::is_same<typename
std::remove_cv< <template-parameter-1-1> >::type,
std::filesystem::__cxx11::path> >, std::__not_<std::is_void<typename
std::remove_pointer<_Tp>::type> >,
std::filesystem::__cxx11::__detail::__constructible_from<_Tp1, _Tp2> >::value,
std::filesystem::__cxx11::path>::type [with _Tp1 = volatile bool; _Tp2 = void]'
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:223:7:  
required by substitution of 'template<class _Source, class _Require>
std::filesystem::__cxx11::path::path(const _Source&,
std::filesystem::__cxx11::path::format) [with _Source = volatile bool; _Require
= <missing>]'
<source>:27:17:   required from here
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:99:5: note:
candidate: 'template<class _CharT, class _Traits, class _Alloc>
std::filesystem::__cxx11::__detail::__is_encoded_char<_CharT>
std::filesystem::__cxx11::__detail::__is_path_src(const
std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&, int)'
   99 |     __is_path_src(const basic_string<_CharT, _Traits, _Alloc>&, int);
      |     ^~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:99:5: note:
  template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:119:29:
note:   mismatched types 'const std::__cxx11::basic_string<_CharT, _Traits,
_Allocator>' and 'volatile bool'
  119 |     : decltype(__is_path_src(std::declval<_Source>(), 0))
      |                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:103:5:
note: candidate: 'template<class _CharT, class _Traits>
std::filesystem::__cxx11::__detail::__is_encoded_char<_CharT>
std::filesystem::__cxx11::__detail::__is_path_src(const
std::basic_string_view<_CharT, _Traits>&, int)'
  103 |     __is_path_src(const basic_string_view<_CharT, _Traits>&, int);
      |     ^~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:103:5:
note:   template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:119:29:
note:   mismatched types 'const std::basic_string_view<_CharT, _Traits>' and
'volatile bool'
  119 |     : decltype(__is_path_src(std::declval<_Source>(), 0))
      |                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:107:5:
note: candidate: 'std::false_type
std::filesystem::__cxx11::__detail::__is_path_src(const _Unknown&, ...) [with
_Unknown = volatile bool; std::false_type = std::integral_constant<bool,
false>]' (near match)
  107 |     __is_path_src(const _Unknown&, ...);
      |     ^~~~~~~~~~~~~
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:107:5:
note:   conversion of argument 1 would be ill-formed:
/opt/compiler-explorer/gcc-10.3.0/include/c++/10.3.0/bits/fs_path.h:119:29:
error: cannot bind non-const lvalue reference of type 'const volatile bool&' to
an rvalue of type 'volatile bool'
  119 |     : decltype(__is_path_src(std::declval<_Source>(), 0))
      |                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
Execution build compiler returned: 1



It seems that it works in gcc 11, and I guess this comes from this commit:

commit 988b853f9c829742907ae22ac66de56facfc7bc5
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Sat May 23 07:28:40 2020 +0100

    libstdc++: Simplify filesystem::path SFINAE constraints

(which seems to have a few follow-up commits to fix some issues).

Shall these SFINAE changes be backported to gcc 9/10 (and I know that gcc 8 was
just closed, but in my case I would be interested by a gcc 8 backport too) ?

Cheers,
Romain

Reply via email to