diff options
author | Jason Merrill <jason@redhat.com> | 2010-02-18 11:27:18 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2010-02-18 11:27:18 -0500 |
commit | 04daa92ba7e36a63dfd7bb1b5959d8afa187ecd1 (patch) | |
tree | f48f260ba50e9024ae229afffa80939640581a5c /gcc | |
parent | 935c0a5d24f70295aee602e4dcdff465d1931024 (diff) | |
download | gcc-04daa92ba7e36a63dfd7bb1b5959d8afa187ecd1.zip gcc-04daa92ba7e36a63dfd7bb1b5959d8afa187ecd1.tar.gz gcc-04daa92ba7e36a63dfd7bb1b5959d8afa187ecd1.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/parser.c | 5 | ||||
-rw-r--r-- | gcc/cp/pt.c | 60 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/dependent-name6.C | 17 |
6 files changed, 84 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 357b925..1fdeef4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 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 * semantics.c (begin_class_definition): Don't crash on unnamed ns. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b5330a3..8b5bb56 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4896,6 +4896,7 @@ extern tree process_template_parm (tree, location_t, tree, bool, bool); extern tree end_template_parm_list (tree); 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 tree push_template_decl (tree); extern tree push_template_decl_real (tree, bool); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 690f2c0..55d0517 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13477,6 +13477,11 @@ cp_parser_init_declarator (cp_parser* parser, we compute it now. */ 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 and attributes. */ if (cp_parser_allow_gnu_extensions_p (parser)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0165a7d..9e159a2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3672,6 +3672,55 @@ current_template_args (void) 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 template PARMS. If MEMBER_TEMPLATE_P is true, the new template is a member template. Used by push_template_decl below. */ @@ -10609,14 +10658,9 @@ tsubst_qualified_id (tree qualified_id, tree args, else expr = name; - if (dependent_type_p (scope)) - { - 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)); - } + if (dependent_scope_p (scope)) + return build_qualified_name (NULL_TREE, scope, expr, + QUALIFIED_NAME_IS_TEMPLATE (qualified_id)); if (!BASELINK_P (name) && !DECL_P (expr)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dbc8226..4225d99 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2010-02-18 Jason Merrill <jason@redhat.com> + PR c++/26261 + * g++.dg/template/dependent-name6.C: New. + PR c++/43109 * g++.dg/parse/namespace12.C: New. diff --git a/gcc/testsuite/g++.dg/template/dependent-name6.C b/gcc/testsuite/g++.dg/template/dependent-name6.C new file mode 100644 index 0000000..e08bbe1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name6.C @@ -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>(); +} |