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