From: Marek Polacek Date: Thu, 15 Aug 2024 15:53:10 +0000 (-0400) Subject: c++: fix ICE in convert_nontype_argument [PR116384] X-Git-Tag: basepoints/gcc-16~6527 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8191f15022b0ea44fcb549449b0458d07ae02e0a;p=thirdparty%2Fgcc.git c++: fix ICE in convert_nontype_argument [PR116384] Here we ICE since r14-8291 in C++11/C++14 modes. Fortunately this is an easy one. The important bit of r14-8291 is this: @@ -20056,9 +20071,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) RETURN (retval); } if (IMPLICIT_CONV_EXPR_NONTYPE_ARG (t)) - /* We'll pass this to convert_nontype_argument again, we don't need - to actually perform any conversion here. */ - RETURN (expr); + { + tree r = convert_nontype_argument (type, expr, complain); + if (r == NULL_TREE) + r = error_mark_node; + RETURN (r); + } which obviously means that instead of returning right away we go to convert_nontype_argument. When type is error_mark_node and we're in C++17, in convert_nontype_argument we go down this path: else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type) || cxx_dialect >= cxx17) { expr = build_converted_constant_expr (type, expr, complain); if (expr == error_mark_node) return (complain & tf_error) ? NULL_TREE : error_mark_node; // ... } but pre-C++17, we take a different route and end up crashing on gcc_unreachable. It would of course also work to check for error_mark_node early in build_converted_constant_expr. PR c++/116384 gcc/cp/ChangeLog: * pt.cc (tsubst_expr) : Bail if tsubst returns error_mark_node. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/vt-116384.C: New test. --- diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 8725a5eeb3f..684ee0c8a60 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -20217,6 +20217,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) case IMPLICIT_CONV_EXPR: { tree type = tsubst (TREE_TYPE (t), args, complain, in_decl); + if (type == error_mark_node) + RETURN (error_mark_node); tree expr = RECUR (TREE_OPERAND (t, 0)); if (dependent_type_p (type) || type_dependent_expression_p (expr)) { diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-116384.C b/gcc/testsuite/g++.dg/cpp0x/vt-116384.C new file mode 100644 index 00000000000..54d7f0774c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/vt-116384.C @@ -0,0 +1,26 @@ +// PR c++/116384 +// { dg-do compile { target c++11 } } + +namespace a { +template struct c; +template struct d; +} +namespace e { +namespace g { +template using h = void; +template class, typename...> struct detector {}; +template