diff options
author | Jason Merrill <jason@redhat.com> | 2016-07-24 19:40:05 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-07-24 19:40:05 -0400 |
commit | 8a61db89b2da509e9cb72c5e6d6fe463c8d22fbf (patch) | |
tree | 717147bc17259f9655b02c65bb56fddb9ccf43d1 /gcc | |
parent | 635c1074bec1f91d4c210b1b66cf910220fa13a5 (diff) | |
download | gcc-8a61db89b2da509e9cb72c5e6d6fe463c8d22fbf.zip gcc-8a61db89b2da509e9cb72c5e6d6fe463c8d22fbf.tar.gz gcc-8a61db89b2da509e9cb72c5e6d6fe463c8d22fbf.tar.bz2 |
PR c++/71515 - typename in partial specialization
* pt.c (resolve_typename_type): Try to avoid calling
currently_open_class.
From-SVN: r238696
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/typename22.C | 8 |
3 files changed, 25 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6c5b5de..b5d816d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-07-24 Jason Merrill <jason@redhat.com> + + PR c++/71515 + * pt.c (resolve_typename_type): Try to avoid calling + currently_open_class. + 2016-07-23 Jason Merrill <jason@redhat.com> PR c++/66617 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 65fa982..a61f1c8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -23678,29 +23678,26 @@ resolve_typename_type (tree type, bool only_current_p) } /* If we don't know what SCOPE refers to, then we cannot resolve the TYPENAME_TYPE. */ - if (TREE_CODE (scope) == TYPENAME_TYPE) - return type; - /* If the SCOPE is a template type parameter, we have no way of - resolving the name. */ - if (TREE_CODE (scope) == TEMPLATE_TYPE_PARM) - return type; - /* If the SCOPE is not the current instantiation, there's no reason - to look inside it. */ - if (only_current_p && !currently_open_class (scope)) + if (!CLASS_TYPE_P (scope)) return type; /* If this is a typedef, we don't want to look inside (c++/11987). */ if (typedef_variant_p (type)) return type; /* If SCOPE isn't the template itself, it will not have a valid TYPE_FIELDS list. */ - if (CLASS_TYPE_P (scope) - && same_type_p (scope, CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope))) + if (same_type_p (scope, CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope))) /* scope is either the template itself or a compatible instantiation like X<T>, so look up the name in the original template. */ scope = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope); - else - /* scope is a partial instantiation, so we can't do the lookup or we - will lose the template arguments. */ + /* We shouldn't have built a TYPENAME_TYPE with a non-dependent scope. */ + gcc_checking_assert (uses_template_parms (scope)); + /* If scope has no fields, it can't be a current instantiation. Check this + before currently_open_class to avoid infinite recursion (71515). */ + if (!TYPE_FIELDS (scope)) + return type; + /* If the SCOPE is not the current instantiation, there's no reason + to look inside it. */ + if (only_current_p && !currently_open_class (scope)) return type; /* Enter the SCOPE so that name lookup will be resolved as if we were in the class definition. In particular, SCOPE will no diff --git a/gcc/testsuite/g++.dg/template/typename22.C b/gcc/testsuite/g++.dg/template/typename22.C new file mode 100644 index 0000000..b5dc1b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typename22.C @@ -0,0 +1,8 @@ +// PR c++/71515 + +template < typename, typename = int > struct A; + +template < typename T > struct A < T, typename A < T >::type > +{ + A < int > *a; +}; |