diff options
-rw-r--r-- | gcc/cp/semantics.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/access32.C | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/access33.C | 9 |
3 files changed, 32 insertions, 5 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b448efe..c6b4c70 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2107,14 +2107,24 @@ check_accessibility_of_qualified_id (tree decl, /* If the reference is to a non-static member of the current class, treat it as if it were referenced through `this'. */ - tree ct; if (DECL_NONSTATIC_MEMBER_P (decl) - && current_class_ptr - && DERIVED_FROM_P (scope, ct = current_nonlambda_class_type ())) - qualifying_type = ct; + && current_class_ptr) + if (tree current = current_nonlambda_class_type ()) + { + if (dependent_type_p (current)) + /* In general we can't know whether this access goes through + `this' until instantiation time. Punt now, or else we might + create a deferred access check that's not relative to `this' + when it ought to be. We'll check this access again after + substitution, e.g. from tsubst_qualified_id. */ + return true; + + if (DERIVED_FROM_P (scope, current)) + qualifying_type = current; + } /* Otherwise, use the type indicated by the nested-name-specifier. */ - else + if (!qualifying_type) qualifying_type = nested_name_specifier; } else diff --git a/gcc/testsuite/g++.dg/template/access32.C b/gcc/testsuite/g++.dg/template/access32.C new file mode 100644 index 0000000..08faa9f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access32.C @@ -0,0 +1,8 @@ +// PR c++/98515 +// { dg-do compile } + +struct A { protected: int var0; }; +template <class> struct B : public A { }; +template <class T> struct C : public B<T> { void g(); }; +template <class T> void C<T>::g() { A::var0++; } +template class C<int>; diff --git a/gcc/testsuite/g++.dg/template/access33.C b/gcc/testsuite/g++.dg/template/access33.C new file mode 100644 index 0000000..9fb9b9a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access33.C @@ -0,0 +1,9 @@ +// PR c++/98515 +// { dg-do compile } + +struct A { protected: int var0; }; +template <class> struct B : public A { }; +template <class T> struct C : public B<T> { void g(); }; +template <class T> void C<T>::g() { A::var0++; } // { dg-error "protected|invalid" } +template <> struct B<char> { }; +template class C<char>; |