mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-13 09:24:41 +08:00
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
This commit is contained in:
parent
342ebbda0f
commit
4d3999876e
@ -1,3 +1,10 @@
|
||||
2012-09-17 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/54575
|
||||
* pt.c (instantiate_alias_template): New.
|
||||
(tsubst): Use it.
|
||||
(push_access_scope): Allow TYPE_DECL.
|
||||
|
||||
2012-09-14 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/53661
|
||||
|
45
gcc/cp/pt.c
45
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. */
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2012-09-17 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/54575
|
||||
* g++.dg/cpp0x/alias-decl-21.C: New.
|
||||
* g++.dg/cpp0x/alias-decl-22.C: New.
|
||||
|
||||
2012-09-17 Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
PR fortran/54608
|
||||
|
23
gcc/testsuite/g++.dg/cpp0x/alias-decl-21.C
Normal file
23
gcc/testsuite/g++.dg/cpp0x/alias-decl-21.C
Normal file
@ -0,0 +1,23 @@
|
||||
// PR c++/54575
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
template<typename _From, typename _To>
|
||||
struct is_convertible { static const bool value = true; };
|
||||
|
||||
template<bool> struct enable_if { };
|
||||
template<> struct enable_if<true> { typedef int type; };
|
||||
|
||||
template<typename _InIter>
|
||||
using _RequireInputIter
|
||||
= typename enable_if<is_convertible<_InIter,bool>::value>::type;
|
||||
|
||||
template<typename _Tp> struct X {
|
||||
template<typename _InputIterator,
|
||||
typename = _RequireInputIter<_InputIterator>>
|
||||
void insert(_InputIterator) {}
|
||||
};
|
||||
|
||||
template<typename> void foo() {
|
||||
X<int> subdomain_indices;
|
||||
subdomain_indices.insert(0);
|
||||
}
|
12
gcc/testsuite/g++.dg/cpp0x/alias-decl-22.C
Normal file
12
gcc/testsuite/g++.dg/cpp0x/alias-decl-22.C
Normal file
@ -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 <class T>
|
||||
using foo = typename T::bar; // { dg-error "this context" }
|
||||
|
||||
class B
|
||||
{
|
||||
typedef int bar; // { dg-error "private" }
|
||||
foo<B> f; // { dg-message "required" }
|
||||
};
|
Loading…
Reference in New Issue
Block a user