http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59482
--- Comment #1 from Ville Voutilainen <ville.voutilainen at gmail dot com> --- A friend function can access the private class, thus void f(); struct B { friend void f(); private: struct C {};}; void f() { struct D : B::C{}; } Some analysis follows: I investigated this a bit. The right place seemed to be enforce_access in search.c, and that then ends up in accessible_p. From there we go to friend_accessible_p, which returns false. The problem is that the current_scope() in accessible_p is NAMESPACE_DECL, and we should perhaps already be in a class scope, since we're dealing with the base-clause. Now that we get NAMESPACE_DECL, there are no befriended_classes for it. Then again, it's probably not that simple. I guess we shouldn't willy-nilly make the compiler think it's in a class scope when dealing with a base-clause, so that lookup doesn't look into the class yet. Any guidance as to "what now?" would be appreciated. I'll dump the backtrace how we get to current_scope, hope that helps. (I must admit I stand at least _some chance_ of figuring things out with a debugger with my puny gcc skills, but not much of a chance...) If you need any trees to be printed, I can certainly provide them. #0 current_scope () at ../../gcc/cp/search.c:526 #1 0x00000000006be0c5 in accessible_p (type=0x7ffff1af64e0, decl=0x7ffff1ae8b80, consider_local_p=<optimized out>) at ../../gcc/cp/search.c:873 #2 0x0000000000540e0d in enforce_access (basetype_path=<optimized out>, decl=0x7ffff1ae8b80, diag_decl=0x7ffff1ae8b80, complain=3) at ../../gcc/cp/call.c:5753 #3 0x00000000006c72a0 in perform_or_defer_access_check (binfo=0x7ffff1ae8b80, decl=0x7ffff1ae8b80, diag_decl=0x7ffff19b5000, complain=0) at ../../gcc/cp/semantics.c:340 #4 0x0000000000641b2f in cp_parser_lookup_name (parser=parser@entry=0x7ffff1afb000, name=name@entry=0x7ffff1afad68, tag_type=tag_type@entry=typename_type, is_template=is_template@entry=false, is_namespace=is_namespace@entry=false, check_dependency=<optimized out>, ambiguous_decls=ambiguous_decls@entry=0x7fffffffd708, name_location=91) at ../../gcc/cp/parser.c:22155 #5 0x00000000006626d9 in cp_parser_class_name (parser=parser@entry=0x7ffff1afb000, typename_keyword_p=<optimized out>, template_keyword_p=<optimized out>, tag_type=tag_type@entry=typename_type, check_dependency_p=check_dependency_p@entry=true, class_head_p=class_head_p@entry=false, is_declaration=is_declaration@entry=true) at ../../gcc/cp/parser.c:19023 #6 0x000000000064b89d in cp_parser_base_specifier (parser=0x7ffff1afb000) at ../../gcc/cp/parser.c:20747 #7 cp_parser_base_clause (parser=0x7ffff1afb000) at ../../gcc/cp/parser.c:20577 #8 cp_parser_class_head (nested_name_specifier_p=<synthetic pointer>, parser=0x7ffff1afb000) at ../../gcc/cp/parser.c:19824 #9 cp_parser_class_specifier_1 (parser=0x7ffff1afb000) at ../../gcc/cp/parser.c:19119 #10 cp_parser_class_specifier (parser=0x7ffff1afb000) at ../../gcc/cp/parser.c:19401 #11 cp_parser_type_specifier (parser=parser@entry=0x7ffff1afb000, flags=flags@entry=1, decl_specs=decl_specs@entry=0x7fffffffd8e0, is_declaration=is_declaration@entry=true, declares_class_or_enum=declares_class_or_enum@entry=0x7fffffffd85c, is_cv_qualifier=is_cv_qualifier@entry=0x7fffffffd85b) at ../../gcc/cp/parser.c:14292 #12 0x0000000000662ba0 in cp_parser_decl_specifier_seq (parser=parser@entry=0x7ffff1afb000, flags=flags@entry=1, decl_specs=decl_specs@entry=0x7fffffffd8e0, declares_class_or_enum=declares_class_or_enum@entry=0x7fffffffd8dc) at ../../gcc/cp/parser.c:11537 #13 0x000000000066972a in cp_parser_simple_declaration (parser=parser@entry=0x7ffff1afb000, function_definition_allowed_p=function_definition_allowed_p@entry=true, maybe_range_for_decl=maybe_range_for_decl@entry=0x0) at ../../gcc/cp/parser.c:11127 #14 0x000000000064d2a4 in cp_parser_block_declaration (parser=0x7ffff1afb000, statement_p=<optimized out>) at ../../gcc/cp/parser.c:11076 #15 0x0000000000673fa4 in cp_parser_declaration (parser=parser@entry=0x7ffff1afb000) at ../../gcc/cp/parser.c:10973 #16 0x0000000000672c99 in cp_parser_declaration_seq_opt (parser=parser@entry=0x7ffff1afb000) at ../../gcc/cp/parser.c:10859 #17 0x000000000067458b in cp_parser_translation_unit (parser=0x7ffff1afb000) at ../../gcc/cp/parser.c:4018 #18 c_parse_file () at ../../gcc/cp/parser.c:31322 #19 0x0000000000796444 in c_common_parse_file () at ../../gcc/c-family/c-opts.c:1056 #20 0x0000000000b46fd6 in compile_file () at ../../gcc/toplev.c:547 #21 0x0000000000b48f98 in do_compile () at ../../gcc/toplev.c:1887 #22 toplev_main (argc=31, argv=0x7fffffffdc18) at ../../gcc/toplev.c:1963 #23 0x00000030a0421735 in __libc_start_main (main=0x53d970 <main(int, char**)>, argc=31, ubp_av=0x7fffffffdc18, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdc08) at libc-start.c:226 #24 0x000000000053d9f1 in _start () (gdb)