Created attachment 36023 [details] The code which produces the bug In the attachment you find code which I'm trying to compile with g++. I have a archlinux system and I have g++ version 5.1.0 from the offical repo of my system. I'm trying to compile the attached code by invoking `g++ classtest.cpp`. gcc fires the error: classtest.cpp: In constructor ‘DerivedB::DerivedB()’: classtest.cpp:9:5: error: ‘int BaseClass::x’ is protected int BaseClass::x; ^ classtest.cpp:22:32: error: within this context std::cout << DerivedA::x; ^ What I'm trying to achieve is completely legal according to the c++ standard ([class.access.base]/p5 ). More information, discussion, and a lot of people who agree that this is indeed a gcc bug, can be found in the associated stackoverflow question: http://stackoverflow.com/questions/31389470/g-compilation-error-is-protected-from-within-this-context-while-clang-do
class BaseClass { protected: static int x; }; struct DerivedA : BaseClass { }; struct DerivedB : BaseClass { DerivedB() { (void) DerivedA::x; } };
This seems to have been broken by the fix for bug 38579. I'll revert it in the open release branches.
Author: jason Date: Tue Aug 18 14:43:44 2015 New Revision: 226974 URL: https://gcc.gnu.org/viewcvs?rev=226974&root=gcc&view=rev Log: PR c++/66957 * search.c (protected_accessible_p): Revert fix for 38579. Added: branches/gcc-4_9-branch/gcc/testsuite/g++.dg/inherit/access9.C Modified: branches/gcc-4_9-branch/gcc/cp/ChangeLog branches/gcc-4_9-branch/gcc/cp/search.c branches/gcc-4_9-branch/gcc/testsuite/g++.dg/conversion/access1.C
Author: jason Date: Tue Aug 18 14:44:06 2015 New Revision: 226975 URL: https://gcc.gnu.org/viewcvs?rev=226975&root=gcc&view=rev Log: PR c++/66957 * search.c (protected_accessible_p): Revert fix for 38579. Added: branches/gcc-5-branch/gcc/testsuite/g++.dg/inherit/access9.C Modified: branches/gcc-5-branch/gcc/cp/ChangeLog branches/gcc-5-branch/gcc/cp/search.c branches/gcc-5-branch/gcc/testsuite/g++.dg/conversion/access1.C
Author: jason Date: Thu Aug 20 01:45:49 2015 New Revision: 227023 URL: https://gcc.gnu.org/viewcvs?rev=227023&root=gcc&view=rev Log: PR c++/66957 * search.c (protected_accessible_p): Remove redundant access_in_type. Add otype parm instead of walking binfo. (friend_accessible_p): Check SCOPE itself. Handle class templates. Pass through otype. (dfs_accessible_post): Handle all accessibility cases. (dfs_accessible_pre): New. (accessible_p): Use it. Don't check protected access here. Pass decl and otype to dfs_walk. (member_declared_in_type, dfs_access_in_type_pre): New. (access_in_type): Use dfs_access_in_type_pre. * friend.c (add_friend): Fix multiple friends with the same name. Added: trunk/gcc/testsuite/g++.dg/inherit/access9.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/friend.c trunk/gcc/cp/search.c
Fixed for 4.9.4, 5.3, 6.0.
For what it's worth, this patch looked like it might also fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58972, and it does.
The fix for this bug seems to have broken N4381-style customization points (http://wg21.link/n4381). To wit, this program used to compile: template <class T> T&& declval(); namespace X { namespace Y { int f(auto&&); struct fn { constexpr auto operator()(auto&& o) const { return f(o); } }; } namespace { constexpr auto f = Y::fn{}; } struct A {}; struct B { friend double f(B&); }; } static_assert(__is_same_as(int, decltype(X::f(declval<X::A&>())))); static_assert(__is_same_as(double, decltype(X::f(declval<X::B&>())))); but now results in the error "error: ‘f’ is not a member of ‘X’" for both static_asserts. It's possible to workaround the error be declaring the anonymous namespace inline: inline namespace { constexpr auto f = Y::fn{}; } It appears that the non-visible friend function f declared in B is incorrectly blocking name lookup of X::f before the phase of lookup that considers namespaces nominated by using directives (such as unnamed namespaces).