My patch to build_static_cast to do type checking in templates ended
up calling some functions that should only be used in non-template
context.  Fixed thus.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit ba91f219897ce6e205bbdc6776de48f02fbd4a57
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Nov 13 12:37:57 2017 -0500

            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.

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> class b {
+  b(b &&c) : d(static_cast<a &&>(c.d)) {}
+  a d;
+};

Reply via email to