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,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));

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