https://gcc.gnu.org/g:6341d34747a6ac554e70ec1e0e39f1bece3506d3
commit r17-4856-g6341d34747a6ac554e70ec1e0e39f1bece3506d3 Author: Jakub Jelinek <[email protected]> Date: Sat Oct 3 21:29:06 2026 +0200 c++: Fix up mangling of __builtin_{bswap,bitreverse}g calls [PR127668] The following testcases ICE during mangling, the dependent __builtin_{bswap,bitreverse}g calls (where those identifiers we treat as keywords and don't even have such builtins, given that those are the first type-generic builtins with the return type dependent on the argument type(s)) are emitted as internal fn calls (IFN_BSWAP or IFN_BITREVERSE), and during mangling we just ICE on any calls to internal functions. The following patch mangles those 2 calls like we mangle e.g. template <typename T> auto foo (T t) -> decltype (__builtin_popcountg (t)) { return t; } template int foo <unsigned> (unsigned); - _Z3fooIjEDTcl19__builtin_popcountgfp_EET_ . In that case it is a type-generic builtin with a fixed return type and we trigger the /* Mangle a dependent name as the name, not whatever happens to be the first function in the overload set. */ if (OVL_P (fn) && type_dependent_expression_p_push (expr)) fn = OVL_NAME (fn); case in the CALL_EXPR write_expression handling, so fn is then an identifier. 2026-10-03 Jakub Jelinek <[email protected]> PR c++/127668 * mangle.cc (write_expression): Handle mangling of calls to IFN_BSWAP and IFN_BITREVERSE. * g++.dg/ext/builtin-bswapg-1.C: New test. * g++.dg/ext/builtin-bitreverseg-1.C: New test. Reviewed-by: Jason Merrill <[email protected]> Diff: --- gcc/cp/mangle.cc | 39 ++++++++++++++++-------- gcc/testsuite/g++.dg/ext/builtin-bitreverseg-1.C | 8 +++++ gcc/testsuite/g++.dg/ext/builtin-bswapg-1.C | 8 +++++ 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index 739ab2afd60e..26da14ffc5e8 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -4094,20 +4094,35 @@ write_expression (tree expr) switch (code) { case CALL_EXPR: - { - tree fn = CALL_EXPR_FN (expr); - - if (TREE_CODE (fn) == ADDR_EXPR) - fn = TREE_OPERAND (fn, 0); + if (tree fn = CALL_EXPR_FN (expr)) + { + if (TREE_CODE (fn) == ADDR_EXPR) + fn = TREE_OPERAND (fn, 0); - /* Mangle a dependent name as the name, not whatever happens to - be the first function in the overload set. */ - if (OVL_P (fn) - && type_dependent_expression_p_push (expr)) - fn = OVL_NAME (fn); + /* Mangle a dependent name as the name, not whatever happens to + be the first function in the overload set. */ + if (OVL_P (fn) + && type_dependent_expression_p_push (expr)) + fn = OVL_NAME (fn); - write_expression (fn); - } + write_expression (fn); + } + else + switch (CALL_EXPR_IFN (expr)) + { + /* Calls to __builtin_bswapg/__builtin_bitreverseg are parsed + as IFN_BSWAP/IFN_BITREVERSE calls because we don't have + those builtins but instead keywords. Pretend they are + builtin function template. */ + case IFN_BSWAP: + write_source_name (get_identifier ("__builtin_bswapg")); + break; + case IFN_BITREVERSE: + write_source_name (get_identifier ("__builtin_bitreverseg")); + break; + default: + gcc_unreachable (); + } for (i = 0; i < call_expr_nargs (expr); ++i) write_expression (CALL_EXPR_ARG (expr, i)); diff --git a/gcc/testsuite/g++.dg/ext/builtin-bitreverseg-1.C b/gcc/testsuite/g++.dg/ext/builtin-bitreverseg-1.C new file mode 100644 index 000000000000..f6cd4a1ffa68 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin-bitreverseg-1.C @@ -0,0 +1,8 @@ +// PR c++/127668 +// { dg-do compile { target c++11 } } +// { dg-final { scan-assembler "_Z3fooIjEDTcl21__builtin_bitreversegfp_EET_" } } + +template <typename T> +auto foo (T t) -> decltype (__builtin_bitreverseg (t)) { return t; } + +template unsigned foo <unsigned> (unsigned); diff --git a/gcc/testsuite/g++.dg/ext/builtin-bswapg-1.C b/gcc/testsuite/g++.dg/ext/builtin-bswapg-1.C new file mode 100644 index 000000000000..d3ae993a3036 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/builtin-bswapg-1.C @@ -0,0 +1,8 @@ +// PR c++/127668 +// { dg-do compile { target c++11 } } +// { dg-final { scan-assembler "_Z3fooIjEDTcl16__builtin_bswapgfp_EET_" } } + +template <typename T> +auto foo (T t) -> decltype (__builtin_bswapg (t)) { return t; } + +template unsigned foo <unsigned> (unsigned);
