My patch for 10200 caused finish_id_expression for Wrap to return the
actual overload set rather than the plain identifier, and we stored
that set in the template CALL_EXPR, but then at instantiation time we
failed to go through and replace it with the instantiated overload
set.  This patch avoids this problem by reverting to the identifier
when we build the CALL_EXPR.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 32c5b130ecdc5eaa6287e1be3abd0794b4bcd129
Author: Jason Merrill <ja...@redhat.com>
Date:   Tue May 30 15:31:38 2017 -0400

            PR c++/80856 - ICE with local extern in template
    
            * semantics.c (finish_call_expr): Replace a local extern overload
            set in a template with the IDENTIFIER_NODE.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index ae03ef6..7269c09 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2316,13 +2316,23 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, 
bool disallow_virtual,
 
   if (processing_template_decl)
     {
+      /* If FN is a local extern declaration or set thereof, look them up
+        again at instantiation time.  */
+      if (is_overloaded_fn (fn))
+       {
+         tree ifn = get_first_fn (fn);
+         if (TREE_CODE (ifn) == FUNCTION_DECL
+             && DECL_LOCAL_FUNCTION_P (ifn))
+           orig_fn = DECL_NAME (ifn);
+       }
+
       /* If the call expression is dependent, build a CALL_EXPR node
         with no type; type_dependent_expression_p recognizes
         expressions with no type as being dependent.  */
       if (type_dependent_expression_p (fn)
          || any_type_dependent_arguments_p (*args))
        {
-         result = build_min_nt_call_vec (fn, *args);
+         result = build_min_nt_call_vec (orig_fn, *args);
          SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location));
          KOENIG_LOOKUP_P (result) = koenig_p;
          if (is_overloaded_fn (fn))
diff --git a/gcc/testsuite/g++.dg/template/local-fn2.C 
b/gcc/testsuite/g++.dg/template/local-fn2.C
new file mode 100644
index 0000000..46fd6cf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/local-fn2.C
@@ -0,0 +1,16 @@
+// PR c++/80856
+
+template<typename T>
+inline T WrapToCycle(T degrees)
+{
+  int Wrap(int x, int lower_bound, int upper_bound);
+  double Wrap(double x, int lower_bound, int upper_bound);
+
+  Wrap(1, 0, 360);
+  return Wrap(degrees, 0, 360);
+}
+
+void GenerateOldReportPage()
+{
+  WrapToCycle(0);
+}

Reply via email to