Skip to content

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

Closed
@judicaelclair

Description

@judicaelclair

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"confirmedVerified by a second party

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions