From: Jason Merrill Date: Mon, 13 Nov 2017 21:49:16 +0000 (-0500) Subject: PR c++/82360 - ICE with static_cast in template. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c360a6681734fcde601f260b02e69bda13d14085;p=gcc.git PR c++/82360 - ICE with static_cast in template. * call.c (perform_direct_initialization_if_possible): Check processing_template_decl. * typeck.c (build_static_cast_1): Likewise. From-SVN: r254710 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 73fa99967ed..37741f6fdc3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2017-11-13 Jason Merrill + + PR c++/82360 - ICE with static_cast in template. + * call.c (perform_direct_initialization_if_possible): Check + processing_template_decl. + * typeck.c (build_static_cast_1): Likewise. + 2017-11-13 Ville Voutilainen Remove the null check from placement new in all modes diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 6875492e687..e6e0f901166 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -10647,6 +10647,16 @@ perform_direct_initialization_if_possible (tree type, LOOKUP_NORMAL, complain); if (!conv || conv->bad_p) expr = NULL_TREE; + else if (processing_template_decl && conv->kind != ck_identity) + { + /* In a template, we are only concerned about determining the + type of non-dependent expressions, so we do not have to + perform the actual conversion. But for initializers, we + need to be able to perform it at instantiation + (or instantiate_non_dependent_expr) time. */ + expr = build1 (IMPLICIT_CONV_EXPR, type, expr); + IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true; + } else expr = convert_like_real (conv, expr, NULL_TREE, 0, /*issue_conversion_warnings=*/false, diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9130c10f390..38ec363dc95 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6820,6 +6820,9 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, { tree base; + if (processing_template_decl) + return expr; + /* There is a standard conversion from "D*" to "B*" even if "B" is ambiguous or inaccessible. If this is really a static_cast, then we check both for inaccessibility and @@ -6864,6 +6867,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, && reference_related_p (TREE_TYPE (type), intype) && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype))) { + if (processing_template_decl) + return expr; if (clk == clk_ordinary) { /* Handle the (non-bit-field) lvalue case here by casting to @@ -6911,6 +6916,9 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, c_cast_p, complain); if (result) { + if (processing_template_decl) + return expr; + result = convert_from_reference (result); /* [expr.static.cast] @@ -6952,7 +6960,11 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, || SCALAR_FLOAT_TYPE_P (type)) && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype) || SCALAR_FLOAT_TYPE_P (intype))) - return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain); + { + if (processing_template_decl) + return expr; + return ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL, complain); + } if (TYPE_PTR_P (type) && TYPE_PTR_P (intype) && CLASS_TYPE_P (TREE_TYPE (type)) @@ -6965,6 +6977,9 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, { tree base; + if (processing_template_decl) + return expr; + if (!c_cast_p && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR, complain)) @@ -7019,6 +7034,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, STATIC_CAST_EXPR, complain)) return error_mark_node; + if (processing_template_decl) + return expr; return convert_ptrmem (type, expr, /*allow_inverse_p=*/1, c_cast_p, complain); } @@ -7038,6 +7055,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR, complain)) return error_mark_node; + if (processing_template_decl) + return expr; return build_nop (type, expr); } diff --git a/gcc/testsuite/g++.dg/template/cast5.C b/gcc/testsuite/g++.dg/template/cast5.C new file mode 100644 index 00000000000..4e48d1d3c5c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/cast5.C @@ -0,0 +1,8 @@ +// PR c++/82360 +// { dg-do compile { target c++11 } } + +class a {}; +template class b { + b(b &&c) : d(static_cast(c.d)) {} + a d; +};