start_preparsed_function (member_function, NULL_TREE,
SF_PRE_PARSED | SF_INCLASS_INLINE);
- /* Don't do access checking if it is a templated function. */
- if (processing_template_decl)
- push_deferring_access_checks (dk_no_check);
-
/* #pragma omp declare reduction needs special parsing. */
if (DECL_OMP_DECLARE_REDUCTION_P (member_function))
{
cp_parser_function_definition_after_declarator (parser,
/*inline_p=*/true);
- if (processing_template_decl)
- pop_deferring_access_checks ();
-
/* Leave the scope of the containing function. */
if (function_scope)
pop_function_context ();
if (DECL_CLASS_SCOPE_P (scope)
&& friend_accessible_p (DECL_CONTEXT (scope), decl, type, otype))
return 1;
+ /* Perhaps SCOPE is a friend function defined inside a class from which
+ DECL is accessible. Checking this is necessary only when the class
+ is dependent, for otherwise add_friend will already have added the
+ class to SCOPE's DECL_BEFRIENDING_CLASSES. */
+ if (tree fctx = DECL_FRIEND_CONTEXT (scope))
+ if (dependent_type_p (fctx)
+ && protected_accessible_p (decl, fctx, type, otype))
+ return 1;
}
/* Maybe scope's template is a friend. */
struct j {
using c = int *;
};
+public:
using as = j::c;
};
template <typename> class k {
--- /dev/null
+// PR c++/58993
+// { dg-do compile }
+
+class base { void foo(); };
+
+template <class T>
+struct bar : public base {
+ void f1() {
+ &base::foo; // { dg-error "private" }
+ }
+
+ template <class>
+ void f2() {
+ &base::foo; // { dg-error "private" }
+ }
+
+ void f3();
+};
+
+template <class T>
+void bar<T>::f3() {
+ (void) &base::foo; // { dg-error "private" }
+}
+
+int main() {
+ bar<int>().f1();
+ bar<int>().f2<int>();
+ bar<int>().f3();
+}
--- /dev/null
+// { dg-do compile }
+
+template <class>
+struct S {
+ S();
+ friend int f(S x) { return x.i + x.j; }
+ template <class T>
+ friend int g(S x, T) { return x.i + x.j; }
+private:
+ int i;
+protected:
+ int j;
+};
--- /dev/null
+// { dg-do compile }
+
+struct A;
+
+struct B {
+ friend struct A;
+private:
+ static void f();
+protected:
+ static void g();
+};
+
+struct A {
+ friend void g(A) {
+ B::f(); // { dg-error "private" }
+ B::g(); // { dg-error "protected" }
+ }
+};