diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-02-26 04:27:51 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-02-26 04:27:51 +0000 |
commit | 9f6822427497c02b5b2255898309877585566efb (patch) | |
tree | 1fd770c7cff40ddfb0640de75e2749f98b8acb28 /gcc/cp/pt.c | |
parent | 812e62a107cb8dd9b948f953d0df85ab130189d6 (diff) | |
download | gcc-9f6822427497c02b5b2255898309877585566efb.tar.gz |
PR c++/56377
* pt.c (fn_type_unification): Wait to call push_tinst_level until
we know what args we're looking at.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@196275 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 51 |
1 files changed, 26 insertions, 25 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5ff08211ebc..9b7fc3a5a4f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14900,19 +14900,6 @@ fn_type_unification (tree fn, tree tinst; tree r = error_mark_node; - /* Adjust any explicit template arguments before entering the - substitution context. */ - if (explicit_targs) - { - explicit_targs - = (coerce_template_parms (tparms, explicit_targs, NULL_TREE, - complain, - /*require_all_args=*/false, - /*use_default_args=*/false)); - if (explicit_targs == error_mark_node) - return error_mark_node; - } - /* In C++0x, it's possible to have a function template whose type depends on itself recursively. This is most obvious with decltype, but can also occur with enumeration scope (c++/48969). So we need to catch infinite @@ -14926,13 +14913,7 @@ fn_type_unification (tree fn, This is, of course, not reentrant. */ if (excessive_deduction_depth) return error_mark_node; - tinst = build_tree_list (fn, targs); - if (!push_tinst_level (tinst)) - { - excessive_deduction_depth = true; - ggc_free (tinst); - return error_mark_node; - } + tinst = build_tree_list (fn, NULL_TREE); ++deduction_depth; push_deferring_access_checks (dk_deferred); @@ -14962,6 +14943,16 @@ fn_type_unification (tree fn, location_t loc = input_location; bool incomplete = false; + /* Adjust any explicit template arguments before entering the + substitution context. */ + explicit_targs + = (coerce_template_parms (tparms, explicit_targs, NULL_TREE, + complain, + /*require_all_args=*/false, + /*use_default_args=*/false)); + if (explicit_targs == error_mark_node) + goto fail; + /* Substitute the explicit args into the function type. This is necessary so that, for instance, explicitly declared function arguments can match null pointed constants. If we were given @@ -15008,14 +14999,19 @@ fn_type_unification (tree fn, } } + TREE_VALUE (tinst) = explicit_targs; + if (!push_tinst_level (tinst)) + { + excessive_deduction_depth = true; + goto fail; + } processing_template_decl += incomplete; input_location = DECL_SOURCE_LOCATION (fn); - TREE_VALUE (tinst) = explicit_targs; fntype = tsubst (TREE_TYPE (fn), explicit_targs, complain | tf_partial, NULL_TREE); - TREE_VALUE (tinst) = targs; input_location = loc; processing_template_decl -= incomplete; + pop_tinst_level (); if (fntype == error_mark_node) goto fail; @@ -15051,11 +15047,9 @@ fn_type_unification (tree fn, callers must be ready to deal with unification failures in any event. */ - pop_tinst_level (); ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), targs, parms, args, nargs, /*subr=*/0, strict, flags, explain_p); - push_tinst_level (tinst); if (!ok) goto fail; @@ -15096,7 +15090,15 @@ fn_type_unification (tree fn, the corresponding deduced argument values. If the substitution results in an invalid type, as described above, type deduction fails. */ + TREE_VALUE (tinst) = targs; + if (!push_tinst_level (tinst)) + { + excessive_deduction_depth = true; + goto fail; + } decl = instantiate_template (fn, targs, complain); + pop_tinst_level (); + if (decl == error_mark_node) goto fail; @@ -15141,7 +15143,6 @@ fn_type_unification (tree fn, excessive_deduction_depth = false; } - pop_tinst_level (); /* We can't free this if a pending_template entry or last_error_tinst_level is pointing at it. */ if (last_pending_template == old_last_pend |