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
This commit is contained in:
Jason Merrill 2018-06-27 13:29:51 -04:00 committed by Jason Merrill
parent 25846b5089
commit 8945521a50
4 changed files with 44 additions and 18 deletions

View file

@ -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

View file

@ -6509,7 +6509,9 @@ 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
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. */
@ -6519,10 +6521,18 @@ do_pushtag (tree name, tree type, tag_scope scope)
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->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));

View file

@ -0,0 +1,9 @@
template <class T>
struct A
{
template <class U>
struct B
{
friend struct C;
};
};

View file

@ -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 ----------------------