llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.84k stars 11.47k forks source link

`std::make_index_sequence` is perhaps mangled incorrectly in return type of template functions #54993

Open royjacobson opened 2 years ago

royjacobson commented 2 years ago

According to the standard, std::make_index_sequence should be an alias to std::integer_sequence. Inside clang we use a special builtin, __make_integer_seq, to implement std::make_index_sequence more efficiently.

Consider

#include <utility>

template<int N>
std::make_index_sequence<N> f() {};
template std::make_index_sequence<1> f<1>();

template<int N>
void g(std::make_index_sequence<N>) {};
template void g<1>(std::make_index_sequence<1>);

void h(std::make_index_sequence<1>) {};

The instantiation of f contains __make_integer_seq in the mangled type of the return value under both libstdc++ and libc++:

__make_integer_seq<std::__1::integer_sequence, unsigned long, 1> f<1>()
_Z1fILi1EE18__make_integer_seqINSt3__116integer_sequenceEmXT_EEv

void g<1>(std::__1::integer_sequence<unsigned long, 0ul>)
_Z1gILi1EEvNSt3__116integer_sequenceImJLm0EEEE

h(std::__1::integer_sequence<unsigned long, 0ul>)
_Z1hNSt3__116integer_sequenceImJLm0EEEE

GCC mangles f as _Z1fILi1EESt16integer_sequenceImJXspcl14__integer_packT_EEEEv. This is at least inconsistent w.r.t to GCC and perhaps violates the standard (since std::make_index_sequence should just be an alias).

llvmbot commented 2 years ago

@llvm/issue-subscribers-clang-frontend

philnik777 commented 2 years ago

I think this shouldn't be marked libc++, since this is a clang builtin problem, not anything that libc++ could fix. Do you agree?

royjacobson commented 2 years ago

You should know better than me :)

My thinking was since it's a built-in that's pretty specific to a stdllib class it's close enough for tagging libcxx as well.

mizvekov commented 2 years ago

This is an ItaniumMangle bug, works fine on MSVC.

This is related to how we store a dependent TemplateSpecializationType for builtin templates, and how ItaniumMangle goes the roundabout way of using the dependent types instead of fully instantiated, non-dependent types.