Hi! We ICE on the following testcase during mangling, finish_compound_literal returns for void{} void_node and the mangler doesn't handle it. Handling void_node in the mangler seems problematic to me, because we don't know for which case it has been created. The following patch arranges to mangle just void{} the same as void() if that is what we want to use, by doing what we do for void() when processing void{}. The code does that only if processing_template_decl, because otherwise build_functional_cast will return void_node, so calling it looks like wasted effort to me. But if you want to call it unconditionally, I can certainly do that too.
Or do you want to mangle it differently? How? clang++ doesn't support DR2351, so I can't check what they are doing. Bootstrapped/regtested on x86_64-linux and i686-linux. 2022-10-19 Jakub Jelinek <ja...@redhat.com> PR c++/106863 * semantics.cc (finish_compound_literal): For void{}, if processing_template_decl return build_functional_cast of NULL_TREE to VOID_TYPE rather than void_node. * g++.dg/cpp0x/dr2351-2.C: New test. --- gcc/cp/semantics.cc.jj 2022-10-10 09:31:57.410985121 +0200 +++ gcc/cp/semantics.cc 2022-10-18 15:24:08.726026118 +0200 @@ -3164,7 +3164,12 @@ finish_compound_literal (tree type, tree { /* DR2351 */ if (VOID_TYPE_P (type) && CONSTRUCTOR_NELTS (compound_literal) == 0) - return void_node; + { + if (!processing_template_decl) + return void_node; + location_t loc = cp_expr_loc_or_input_loc (compound_literal); + return build_functional_cast (loc, type, NULL_TREE, complain); + } else if (VOID_TYPE_P (type) && processing_template_decl && maybe_zero_constructor_nelts (compound_literal)) --- gcc/testsuite/g++.dg/cpp0x/dr2351-2.C.jj 2022-10-18 15:27:01.146690132 +0200 +++ gcc/testsuite/g++.dg/cpp0x/dr2351-2.C 2022-10-18 15:27:39.909164970 +0200 @@ -0,0 +1,16 @@ +// DR2351 +// { dg-do compile { target c++11 } } + +void bar (int); + +template <typename T> +auto foo (T t) -> decltype (bar (t), void{}) +{ + return bar (t); +} + +int +main () +{ + foo (0); +} Jakub