From 4d3999876e3c70b0d6bea7884b24953404055778 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 17 Sep 2012 23:47:35 -0400 Subject: [PATCH] re PR c++/54575 (ICE with std::vector::insert and -std=c++11) PR c++/54575 * pt.c (instantiate_alias_template): New. (tsubst): Use it. (push_access_scope): Allow TYPE_DECL. From-SVN: r191412 --- gcc/cp/ChangeLog | 7 ++++ gcc/cp/pt.c | 45 ++++++++++++++++++---- gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/g++.dg/cpp0x/alias-decl-21.C | 23 +++++++++++ gcc/testsuite/g++.dg/cpp0x/alias-decl-22.C | 12 ++++++ 5 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-21.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-22.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c11a8c20c6b..676c1669298 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2012-09-17 Jason Merrill + + PR c++/54575 + * pt.c (instantiate_alias_template): New. + (tsubst): Use it. + (push_access_scope): Allow TYPE_DECL. + 2012-09-14 Jason Merrill PR c++/53661 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7924dff519f..16952bffa0c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -205,16 +205,18 @@ static tree template_parm_to_arg (tree t); static bool arg_from_parm_pack_p (tree, tree); static tree current_template_args (void); static tree tsubst_template_parm (tree, tree, tsubst_flags_t); +static tree instantiate_alias_template (tree, tree, tsubst_flags_t); /* Make the current scope suitable for access checking when we are processing T. T can be FUNCTION_DECL for instantiated function - template, or VAR_DECL for static member variable (need by - instantiate_decl). */ + template, VAR_DECL for static member variable, or TYPE_DECL for + alias template (needed by instantiate_decl). */ static void push_access_scope (tree t) { gcc_assert (TREE_CODE (t) == FUNCTION_DECL + || TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == VAR_DECL); if (DECL_FRIEND_CONTEXT (t)) @@ -10949,10 +10951,10 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl))) { /* DECL represents an alias template and we want to - instantiate it. Let's substitute our arguments for the - template parameters into the declaration and get the - resulting type. */ - r = tsubst (decl, args, complain, decl); + instantiate it. */ + tree tmpl = most_general_template (DECL_TI_TEMPLATE (decl)); + tree gen_args = tsubst (DECL_TI_ARGS (decl), args, complain, in_decl); + r = instantiate_alias_template (tmpl, gen_args, complain); } else if (DECL_CLASS_SCOPE_P (decl) && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl)) @@ -14377,7 +14379,7 @@ recheck_decl_substitution (tree d, tree tmpl, tree args) pop_access_scope (d); } -/* Instantiate the indicated variable or function template TMPL with +/* Instantiate the indicated variable, function, or alias template TMPL with the template arguments in TARG_PTR. */ static tree @@ -14526,6 +14528,35 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) return ret; } +/* Instantiate the alias template TMPL with ARGS. Also push a template + instantiation level, which instantiate_template doesn't do because + functions and variables have sufficient context established by the + callers. */ + +static tree +instantiate_alias_template (tree tmpl, tree args, tsubst_flags_t complain) +{ + struct pending_template *old_last_pend = last_pending_template; + struct tinst_level *old_error_tinst = last_error_tinst_level; + if (tmpl == error_mark_node || args == error_mark_node) + return error_mark_node; + tree tinst = build_tree_list (tmpl, args); + if (!push_tinst_level (tinst)) + { + ggc_free (tinst); + return error_mark_node; + } + tree r = instantiate_template (tmpl, args, complain); + 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 + && last_error_tinst_level == old_error_tinst) + ggc_free (tinst); + + return r; +} + /* PARM is a template parameter pack for FN. Returns true iff PARM is used in a deducible way in the argument list of FN. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6bebf2eaa92..19e27193671 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-09-17 Jason Merrill + + PR c++/54575 + * g++.dg/cpp0x/alias-decl-21.C: New. + * g++.dg/cpp0x/alias-decl-22.C: New. + 2012-09-17 Tobias Burnus PR fortran/54608 diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-21.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-21.C new file mode 100644 index 00000000000..463f539d38f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-21.C @@ -0,0 +1,23 @@ +// PR c++/54575 +// { dg-do compile { target c++11 } } + +template +struct is_convertible { static const bool value = true; }; + +template struct enable_if { }; +template<> struct enable_if { typedef int type; }; + +template +using _RequireInputIter += typename enable_if::value>::type; + +template struct X { + template> + void insert(_InputIterator) {} +}; + +template void foo() { + X subdomain_indices; + subdomain_indices.insert(0); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-22.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-22.C new file mode 100644 index 00000000000..1f6cb8f40b8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-22.C @@ -0,0 +1,12 @@ +// The standard is unclear about whether this testcase is well-formed. +// Clang considers it well-formed, EDG not. Let's go with EDG for now. +// { dg-do compile { target c++11 } } + +template +using foo = typename T::bar; // { dg-error "this context" } + +class B +{ + typedef int bar; // { dg-error "private" } + foo f; // { dg-message "required" } +};