aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/semantics.c20
-rw-r--r--gcc/testsuite/g++.dg/template/access32.C8
-rw-r--r--gcc/testsuite/g++.dg/template/access33.C9
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>;