diff options
author | Jason Merrill <jason@redhat.com> | 2018-06-27 13:29:51 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2018-06-27 13:29:51 -0400 |
commit | 8945521a50a7dd26ffebdee20a82e323141dfd8b (patch) | |
tree | b87cf8b3c60804210ba30e17be4ab7cde464fd68 /gcc | |
parent | 25846b50895262d38e1271bb19def833f9a63182 (diff) | |
download | gcc-8945521a50a7dd26ffebdee20a82e323141dfd8b.zip gcc-8945521a50a7dd26ffebdee20a82e323141dfd8b.tar.gz gcc-8945521a50a7dd26ffebdee20a82e323141dfd8b.tar.bz2 |
Avoid crash on friend in nested class template.
* name-lookup.c (do_pushtag): If we skip a class level, also skip
its template level.
From-SVN: r262188
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 38 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/friend66.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.law/visibility13.C | 10 |
4 files changed, 44 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 90d1545..05383b6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2018-06-27 Jason Merrill <jason@redhat.com> + + * name-lookup.c (do_pushtag): If we skip a class level, also skip + its template level. + 2018-06-26 Jason Merrill <jason@redhat.com> PR c++/86320 - memory-hog with std::array of pair diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index a30c374..e0500d8 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -6509,20 +6509,30 @@ do_pushtag (tree name, tree type, tag_scope scope) tree decl; cp_binding_level *b = current_binding_level; - while (/* Cleanup scopes are not scopes from the point of view of - the language. */ - b->kind == sk_cleanup - /* Neither are function parameter scopes. */ - || b->kind == sk_function_parms - /* Neither are the scopes used to hold template parameters - for an explicit specialization. For an ordinary template - declaration, these scopes are not scopes from the point of - view of the language. */ - || (b->kind == sk_template_parms - && (b->explicit_spec_p || scope == ts_global)) - || (b->kind == sk_class - && scope != ts_current)) - b = b->level_chain; + while (true) + { + if (/* Cleanup scopes are not scopes from the point of view of + the language. */ + b->kind == sk_cleanup + /* Neither are function parameter scopes. */ + || b->kind == sk_function_parms + /* Neither are the scopes used to hold template parameters + for an explicit specialization. For an ordinary template + declaration, these scopes are not scopes from the point of + view of the language. */ + || (b->kind == sk_template_parms + && (b->explicit_spec_p || scope == ts_global))) + b = b->level_chain; + else if (b->kind == sk_class + && scope != ts_current) + { + b = b->level_chain; + if (b->kind == sk_template_parms) + b = b->level_chain; + } + else + break; + } gcc_assert (identifier_p (name)); diff --git a/gcc/testsuite/g++.dg/template/friend66.C b/gcc/testsuite/g++.dg/template/friend66.C new file mode 100644 index 0000000..f8c95f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend66.C @@ -0,0 +1,9 @@ +template <class T> +struct A +{ + template <class U> + struct B + { + friend struct C; + }; +}; diff --git a/gcc/testsuite/g++.old-deja/g++.law/visibility13.C b/gcc/testsuite/g++.old-deja/g++.law/visibility13.C index 025b0b1..451ef1a 100644 --- a/gcc/testsuite/g++.old-deja/g++.law/visibility13.C +++ b/gcc/testsuite/g++.old-deja/g++.law/visibility13.C @@ -15,9 +15,11 @@ using namespace std; const int ArraySize = 12; +template <class> class Array_RC; + template <class Type> -class Array { // { dg-error "" } .struct Array_RC redecl.* -friend class Array_RC; +class Array { + friend class Array_RC<Type>; public: Array(const Type *ar, int sz) { init(ar,sz); } virtual ~Array() { delete [] ia; } @@ -76,8 +78,8 @@ Array_RC<Type>::Array_RC(const Type *ar, int sz) : Array<Type>(ar, sz) {} template <class Type> Type &Array_RC<Type>::operator[](int ix) { - assert(ix >= 0 && ix < size);// { dg-error "" } member .size.* - return ia[ix];// { dg-error "" } member .ia.* + assert(ix >= 0 && ix < this->size); + return this->ia[ix]; } // ------------------- Test routine ---------------------- |