mirror of git://gcc.gnu.org/git/gcc.git
re PR c++/26261 (Rejects template with const static data member used in return type)
PR c++/26261 PR c++/43101 * pt.c (tsubst_qualified_id): Do normal lookup in non-dependent scope. (maybe_update_decl_type): New fn. * parser.c (cp_parser_init_declarator): Use it. From-SVN: r156865
This commit is contained in:
parent
935c0a5d24
commit
04daa92ba7
|
|
@ -1,5 +1,11 @@
|
||||||
2010-02-18 Jason Merrill <jason@redhat.com>
|
2010-02-18 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
PR c++/26261
|
||||||
|
PR c++/43101
|
||||||
|
* pt.c (tsubst_qualified_id): Do normal lookup in non-dependent scope.
|
||||||
|
(maybe_update_decl_type): New fn.
|
||||||
|
* parser.c (cp_parser_init_declarator): Use it.
|
||||||
|
|
||||||
PR c++/43109
|
PR c++/43109
|
||||||
* semantics.c (begin_class_definition): Don't crash on unnamed ns.
|
* semantics.c (begin_class_definition): Don't crash on unnamed ns.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4896,6 +4896,7 @@ extern tree process_template_parm (tree, location_t, tree,
|
||||||
bool, bool);
|
bool, bool);
|
||||||
extern tree end_template_parm_list (tree);
|
extern tree end_template_parm_list (tree);
|
||||||
extern void end_template_decl (void);
|
extern void end_template_decl (void);
|
||||||
|
extern tree maybe_update_decl_type (tree, tree);
|
||||||
extern bool check_default_tmpl_args (tree, tree, int, int, int);
|
extern bool check_default_tmpl_args (tree, tree, int, int, int);
|
||||||
extern tree push_template_decl (tree);
|
extern tree push_template_decl (tree);
|
||||||
extern tree push_template_decl_real (tree, bool);
|
extern tree push_template_decl_real (tree, bool);
|
||||||
|
|
|
||||||
|
|
@ -13477,6 +13477,11 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||||
we compute it now. */
|
we compute it now. */
|
||||||
scope = get_scope_of_declarator (declarator);
|
scope = get_scope_of_declarator (declarator);
|
||||||
|
|
||||||
|
/* Perform any lookups in the declared type which were thought to be
|
||||||
|
dependent, but are not in the scope of the declarator. */
|
||||||
|
decl_specifiers->type
|
||||||
|
= maybe_update_decl_type (decl_specifiers->type, scope);
|
||||||
|
|
||||||
/* If we're allowing GNU extensions, look for an asm-specification
|
/* If we're allowing GNU extensions, look for an asm-specification
|
||||||
and attributes. */
|
and attributes. */
|
||||||
if (cp_parser_allow_gnu_extensions_p (parser))
|
if (cp_parser_allow_gnu_extensions_p (parser))
|
||||||
|
|
|
||||||
58
gcc/cp/pt.c
58
gcc/cp/pt.c
|
|
@ -3672,6 +3672,55 @@ current_template_args (void)
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update the declared TYPE by doing any lookups which were thought to be
|
||||||
|
dependent, but are not now that we know the SCOPE of the declarator. */
|
||||||
|
|
||||||
|
tree
|
||||||
|
maybe_update_decl_type (tree orig_type, tree scope)
|
||||||
|
{
|
||||||
|
tree type = orig_type;
|
||||||
|
|
||||||
|
if (type == NULL_TREE)
|
||||||
|
return type;
|
||||||
|
|
||||||
|
if (TREE_CODE (orig_type) == TYPE_DECL)
|
||||||
|
type = TREE_TYPE (type);
|
||||||
|
|
||||||
|
if (scope && TYPE_P (scope) && dependent_type_p (scope)
|
||||||
|
&& dependent_type_p (type)
|
||||||
|
/* Don't bother building up the args in this case. */
|
||||||
|
&& TREE_CODE (type) != TEMPLATE_TYPE_PARM)
|
||||||
|
{
|
||||||
|
/* tsubst in the args corresponding to the template parameters,
|
||||||
|
including auto if present. Most things will be unchanged, but
|
||||||
|
make_typename_type and tsubst_qualified_id will resolve
|
||||||
|
TYPENAME_TYPEs and SCOPE_REFs that were previously dependent. */
|
||||||
|
tree args = current_template_args ();
|
||||||
|
tree auto_node = type_uses_auto (type);
|
||||||
|
if (auto_node)
|
||||||
|
{
|
||||||
|
tree auto_vec = make_tree_vec (1);
|
||||||
|
TREE_VEC_ELT (auto_vec, 0) = auto_node;
|
||||||
|
args = add_to_template_args (args, auto_vec);
|
||||||
|
}
|
||||||
|
push_scope (scope);
|
||||||
|
type = tsubst (type, args, tf_warning_or_error, NULL_TREE);
|
||||||
|
pop_scope (scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == error_mark_node)
|
||||||
|
return orig_type;
|
||||||
|
|
||||||
|
if (TREE_CODE (orig_type) == TYPE_DECL)
|
||||||
|
{
|
||||||
|
if (same_type_p (type, TREE_TYPE (orig_type)))
|
||||||
|
type = orig_type;
|
||||||
|
else
|
||||||
|
type = TYPE_NAME (type);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return a TEMPLATE_DECL corresponding to DECL, using the indicated
|
/* Return a TEMPLATE_DECL corresponding to DECL, using the indicated
|
||||||
template PARMS. If MEMBER_TEMPLATE_P is true, the new template is
|
template PARMS. If MEMBER_TEMPLATE_P is true, the new template is
|
||||||
a member template. Used by push_template_decl below. */
|
a member template. Used by push_template_decl below. */
|
||||||
|
|
@ -10609,14 +10658,9 @@ tsubst_qualified_id (tree qualified_id, tree args,
|
||||||
else
|
else
|
||||||
expr = name;
|
expr = name;
|
||||||
|
|
||||||
if (dependent_type_p (scope))
|
if (dependent_scope_p (scope))
|
||||||
{
|
return build_qualified_name (NULL_TREE, scope, expr,
|
||||||
tree type = NULL_TREE;
|
|
||||||
if (DECL_P (expr) && !dependent_scope_p (scope))
|
|
||||||
type = TREE_TYPE (expr);
|
|
||||||
return build_qualified_name (type, scope, expr,
|
|
||||||
QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
|
QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
|
||||||
}
|
|
||||||
|
|
||||||
if (!BASELINK_P (name) && !DECL_P (expr))
|
if (!BASELINK_P (name) && !DECL_P (expr))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
2010-02-18 Jason Merrill <jason@redhat.com>
|
2010-02-18 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
PR c++/26261
|
||||||
|
* g++.dg/template/dependent-name6.C: New.
|
||||||
|
|
||||||
PR c++/43109
|
PR c++/43109
|
||||||
* g++.dg/parse/namespace12.C: New.
|
* g++.dg/parse/namespace12.C: New.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// PR c++/26261
|
||||||
|
// { dg-final { scan-assembler "_ZN1YIiE1fIiEE1XILi1EEv" } }
|
||||||
|
|
||||||
|
template <int dim> class X {};
|
||||||
|
|
||||||
|
template <class T> struct Y {
|
||||||
|
static const unsigned int dim = 1;
|
||||||
|
template <class U> X<Y<T>::dim> f();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T> template <class U>
|
||||||
|
X<Y<T>::dim> Y<T>::f() { return X<dim>(); }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Y<int>().f<int>();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue