diff options
author | Jason Merrill <jason@redhat.com> | 2017-11-13 16:49:16 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-11-13 16:49:16 -0500 |
commit | c360a6681734fcde601f260b02e69bda13d14085 (patch) | |
tree | 0994684b16f8526820ca22aaafcdfe10a126c8d2 /gcc | |
parent | fb771b9dad6ef78a985353128cea48e620eb4324 (diff) | |
download | gcc-c360a6681734fcde601f260b02e69bda13d14085.zip gcc-c360a6681734fcde601f260b02e69bda13d14085.tar.gz gcc-c360a6681734fcde601f260b02e69bda13d14085.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/call.c | 10 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/cast5.C | 8 |
4 files changed, 45 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 73fa999..37741f6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2017-11-13 Jason Merrill <jason@redhat.com> + + 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 <ville.voutilainen@gmail.com> Remove the null check from placement new in all modes diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 6875492..e6e0f90 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 9130c10..38ec363 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 0000000..4e48d1d --- /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> class b { + b(b &&c) : d(static_cast<a &&>(c.d)) {} + a d; +}; |