From 3c1f5a3a6d6425158ee35ef4ff67ac54010190f1 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 30 May 2017 17:13:27 -0400 Subject: [PATCH] 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. From-SVN: r248699 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/semantics.c | 12 +++++++++++- gcc/testsuite/g++.dg/template/local-fn2.C | 21 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/template/local-fn2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2dac610..8cc3ca3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-05-30 Jason Merrill + + 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. + 2017-05-30 David Malcolm * call.c (perform_implicit_conversion_flags): Convert diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 87b9534..99c61e5 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2316,13 +2316,23 @@ finish_call_expr (tree fn, vec **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..98525fd --- /dev/null +++ b/gcc/testsuite/g++.dg/template/local-fn2.C @@ -0,0 +1,21 @@ +// PR c++/80856 +// { dg-do compile { target c++11 } } + +template +inline T WrapToCycle(T degrees) +{ + int Wrap(int x, int lower_bound, int upper_bound); + + auto p = Wrap; + p (1, 0, 360); + + double Wrap(double x, int lower_bound, int upper_bound); + + Wrap(1, 0, 360); + return Wrap(degrees, 0, 360); +} + +void GenerateOldReportPage() +{ + WrapToCycle(0); +} -- 2.7.4