aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-11-13 16:49:16 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-11-13 16:49:16 -0500
commitc360a6681734fcde601f260b02e69bda13d14085 (patch)
tree0994684b16f8526820ca22aaafcdfe10a126c8d2 /gcc
parentfb771b9dad6ef78a985353128cea48e620eb4324 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/call.c10
-rw-r--r--gcc/cp/typeck.c21
-rw-r--r--gcc/testsuite/g++.dg/template/cast5.C8
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;
+};