aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-06-27 13:29:51 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-06-27 13:29:51 -0400
commit8945521a50a7dd26ffebdee20a82e323141dfd8b (patch)
treeb87cf8b3c60804210ba30e17be4ab7cde464fd68 /gcc
parent25846b50895262d38e1271bb19def833f9a63182 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/cp/name-lookup.c38
-rw-r--r--gcc/testsuite/g++.dg/template/friend66.C9
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/visibility13.C10
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 ----------------------