Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x86-64 clang 18 fails to compile nested tuple construction #64466

Closed
judicaelclair opened this issue Aug 5, 2023 · 4 comments
Closed

x86-64 clang 18 fails to compile nested tuple construction #64466

judicaelclair opened this issue Aug 5, 2023 · 4 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party

Comments

@judicaelclair
Copy link

On clang trunk (i.e. 18), I'm getting compile errors for nested construction of tuples with flags -std=c++23 -stdlib=libstdc++. This in turn causes issues with std::make_obj_using_allocator. These errors do not occur if instead compiled with -std=c++20.

For instance, see Godbolt example: https://godbolt.org/z/PPTjbc1s6

The aforementioned example compiles the following:

#include <memory>
#include <string>

using elem_type = std::pair<int, std::pair<int, std::string>>;

void example_0() {
  std::make_tuple(std::make_tuple());
}

void example_1() {
  std::make_tuple(
      std::piecewise_construct, std::make_tuple(),
      std::make_tuple(std::piecewise_construct, std::make_tuple(), std::make_tuple(std::allocator<elem_type>{})));
}

void example_2() {
  std::make_obj_using_allocator<elem_type>(std::allocator<elem_type>{});
}

and produces the following errors:

In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/memory:78:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/unique_ptr.h:36:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:691:2: error: pack expansion contains parameter pack '_UTypes' that has a different length (1 vs. 0) from outer parameter packs
  691 |         using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
      |         ^~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:853:27: note: in instantiation of template type alias '__convertible' requested here
  853 |           = _TCC<true>::template __convertible<_Args...>::value;
      |                                  ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:948:12: note: in instantiation of static data member 'std::tuple<std::tuple<>>::__convertible<>' requested here
  948 |         explicit(!__convertible<_UElements&...>)
      |                   ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1991:28: note: while substituting deduced template arguments into function template 'tuple' [with _UElements = <>]
 1991 |       return __result_type(std::forward<_Elements>(__args)...);
      |                            ^
<source>:7:8: note: in instantiation of function template specialization 'std::make_tuple<std::tuple<>>' requested here
    7 |   std::make_tuple(std::make_tuple());
      |        ^
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/memory:78:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/unique_ptr.h:36:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:691:2: error: pack expansion contains parameter pack '_UTypes' that has a different length (3 vs. 1) from outer parameter packs
  691 |         using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
      |         ^~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:853:27: note: in instantiation of template type alias '__convertible' requested here
  853 |           = _TCC<true>::template __convertible<_Args...>::value;
      |                                  ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:948:12: note: in instantiation of static data member 'std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>::__convertible<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>' requested here
  948 |         explicit(!__convertible<_UElements&...>)
      |                   ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1040:49: note: while substituting deduced template arguments into function template 'tuple' [with _UElements = <std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>]
 1040 |       = __bool_constant<__is_constructible(_Tp, _Args...)>;
      |                                                 ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1046:16: note: in instantiation of template type alias '__is_constructible_impl' requested here
 1046 |       : public __is_constructible_impl<_Tp, _Args...>
      |                ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:161:30: note: in instantiation of template class 'std::is_constructible<std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, const std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>> &>' requested here
  161 |                                       __enable_if_t<bool(_Bn::value)>...>;
      |                                                          ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:177:16: note: (skipping 4 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
  177 |     : decltype(__detail::__and_fn<_Bn...>(0))
      |                ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:768:26: note: in instantiation of function template specialization 'std::_TupleConstraints<true, std::piecewise_construct_t, std::tuple<>, std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>>::__is_implicitly_constructible<const std::piecewise_construct_t &, const std::tuple<> &, const std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>> &>' requested here
  768 |           _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
      |                                 ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1021:53: note: in instantiation of template type alias '_ImplicitCtor' requested here
 1021 |                _ImplicitCtor<_Valid, const _UElements&...> = true>
      |                                                            ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1023:2: note: while substituting prior template arguments into non-type template parameter [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, _Valid = true]
 1023 |         tuple(allocator_arg_t __tag, const _Alloc& __a,
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1024 |               const tuple<_UElements...>& __in)
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1025 |         : _Inherited(__tag, __a,
      |         ~~~~~~~~~~~~~~~~~~~~~~~~
 1026 |                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1027 |         { }
      |         ~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1991:14: note: while substituting deduced template arguments into function template 'tuple' [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, _Valid = (no value), $3 = (no value)]
 1991 |       return __result_type(std::forward<_Elements>(__args)...);
      |              ^
<source>:11:8: note: in instantiation of function template specialization 'std::make_tuple<const std::piecewise_construct_t &, std::tuple<>, std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>>' requested here
   11 |   std::make_tuple(
      |        ^
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/memory:78:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/unique_ptr.h:36:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:691:2: error: pack expansion contains parameter pack '_UTypes' that has a different length (3 vs. 1) from outer parameter packs
  691 |         using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
      |         ^~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:853:27: note: in instantiation of template type alias '__convertible' requested here
  853 |           = _TCC<true>::template __convertible<_Args...>::value;
      |                                  ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:959:12: note: in instantiation of static data member 'std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>::__convertible<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>' requested here
  959 |         explicit(!__convertible<const _UElements...>)
      |                   ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1040:49: note: while substituting deduced template arguments into function template 'tuple' [with _UElements = <std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>]
 1040 |       = __bool_constant<__is_constructible(_Tp, _Args...)>;
      |                                                 ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1046:16: note: in instantiation of template type alias '__is_constructible_impl' requested here
 1046 |       : public __is_constructible_impl<_Tp, _Args...>
      |                ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:161:30: note: in instantiation of template class 'std::is_constructible<std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, const std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>> &>' requested here
  161 |                                       __enable_if_t<bool(_Bn::value)>...>;
      |                                                          ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:177:16: note: (skipping 4 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
  177 |     : decltype(__detail::__and_fn<_Bn...>(0))
      |                ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:768:26: note: in instantiation of function template specialization 'std::_TupleConstraints<true, std::piecewise_construct_t, std::tuple<>, std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>>::__is_implicitly_constructible<const std::piecewise_construct_t &, const std::tuple<> &, const std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>> &>' requested here
  768 |           _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
      |                                 ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1021:53: note: in instantiation of template type alias '_ImplicitCtor' requested here
 1021 |                _ImplicitCtor<_Valid, const _UElements&...> = true>
      |                                                            ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1023:2: note: while substituting prior template arguments into non-type template parameter [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, _Valid = true]
 1023 |         tuple(allocator_arg_t __tag, const _Alloc& __a,
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1024 |               const tuple<_UElements...>& __in)
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1025 |         : _Inherited(__tag, __a,
      |         ~~~~~~~~~~~~~~~~~~~~~~~~
 1026 |                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1027 |         { }
      |         ~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1991:14: note: while substituting deduced template arguments into function template 'tuple' [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>, _Valid = (no value), $3 = (no value)]
 1991 |       return __result_type(std::forward<_Elements>(__args)...);
      |              ^
<source>:11:8: note: in instantiation of function template specialization 'std::make_tuple<const std::piecewise_construct_t &, std::tuple<>, std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>>>' requested here
   11 |   std::make_tuple(
      |        ^
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/memory:78:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/unique_ptr.h:36:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:691:2: error: pack expansion contains parameter pack '_UTypes' that has a different length (3 vs. 1) from outer parameter packs
  691 |         using __convertible = __and_<is_convertible<_UTypes, _Types>...>;
      |         ^~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:853:27: note: in instantiation of template type alias '__convertible' requested here
  853 |           = _TCC<true>::template __convertible<_Args...>::value;
      |                                  ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:948:12: note: in instantiation of static data member 'std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>>::__convertible<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>' requested here
  948 |         explicit(!__convertible<_UElements&...>)
      |                   ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1040:49: note: while substituting deduced template arguments into function template 'tuple' [with _UElements = <const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>]
 1040 |       = __bool_constant<__is_constructible(_Tp, _Args...)>;
      |                                                 ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:1046:16: note: in instantiation of template type alias '__is_constructible_impl' requested here
 1046 |       : public __is_constructible_impl<_Tp, _Args...>
      |                ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:161:30: note: in instantiation of template class 'std::is_constructible<std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>>, const std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &> &>' requested here
  161 |                                       __enable_if_t<bool(_Bn::value)>...>;
      |                                                          ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/type_traits:177:16: note: (skipping 6 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
  177 |     : decltype(__detail::__and_fn<_Bn...>(0))
      |                ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1023:2: note: while substituting prior template arguments into non-type template parameter [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>>, _Valid = true]
 1023 |         tuple(allocator_arg_t __tag, const _Alloc& __a,
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1024 |               const tuple<_UElements...>& __in)
      |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1025 |         : _Inherited(__tag, __a,
      |         ~~~~~~~~~~~~~~~~~~~~~~~~
 1026 |                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 1027 |         { }
      |         ~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/tuple:1991:14: note: while substituting deduced template arguments into function template 'tuple' [with _Alloc = std::tuple<>, _UElements = <std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>>, _Valid = (no value), $3 = (no value)]
 1991 |       return __result_type(std::forward<_Elements>(__args)...);
      |              ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/uses_allocator_args.h:147:19: note: in instantiation of function template specialization 'std::make_tuple<const std::piecewise_construct_t &, std::tuple<>, std::tuple<std::piecewise_construct_t, std::tuple<>, std::tuple<const std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>> &>>>' requested here
  147 |       return std::make_tuple(piecewise_construct,
      |                   ^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/14.0.0/../../../../include/c++/14.0.0/bits/uses_allocator_args.h:233:9: note: in instantiation of function template specialization 'std::uses_allocator_construction_args<std::pair<int, std::pair<int, std::basic_string<char>>>, std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>' requested here
  233 |           std::uses_allocator_construction_args<_Tp>(__a,
      |                ^
<source>:17:8: note: in instantiation of function template specialization 'std::make_obj_using_allocator<std::pair<int, std::pair<int, std::basic_string<char>>>, std::allocator<std::pair<int, std::pair<int, std::basic_string<char>>>>>' requested here
   17 |   std::make_obj_using_allocator<elem_type>(std::allocator<elem_type>{});
      |        ^
4 errors generated.
Compiler returned: 1
@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed new issue labels Aug 5, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Aug 5, 2023

@llvm/issue-subscribers-clang-frontend

@MitalAshok
Copy link
Contributor

MitalAshok commented Aug 5, 2023

Smaller example:

template<typename... Ts>
struct X {
    template<typename... Us>
    static constexpr bool eq = (__is_same(Ts, Us) && ...);
    template<typename... Us> requires (sizeof...(Us) == sizeof...(Ts))
    explicit(eq<Us...>) X(Us...);
    X(...);
};

int main() {
    X<>{0};
}

eq<Us...> is a non-SFINAE error (since it is not an immediate context) if the size of the packs is not the same. However, eq<Us...> (which is eq<int> in this example) shouldn't be instantiated here because the constraint isn't satisfied, which should SFINAE and select the X(...) constructor

@Romain-Geissler-1A
Copy link
Member

Romain-Geissler-1A commented Aug 8, 2023

It seems similar to #61415 (which is supposedly a duplicate of a very long standing issue since forever in clang: #17042)

@vient
Copy link
Member

vient commented Dec 19, 2023

Seems to be fixed in trunk

@shafik shafik added the confirmed Verified by a second party label Dec 19, 2023
@shafik shafik closed this as completed Dec 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party
Projects
None yet
Development

No branches or pull requests

7 participants