This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/38579
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 16 Jan 2009 13:35:14 -0500
- Subject: C++ PATCH for c++/38579
This turns out to be a bug I introduced back in 2000, but nobody noticed
until recently. I don't know what I was thinking when I wrote that
"accessible_p will iterate over various values of N"; in fact what
accessible_p is iterating over is possible values of B in the next
bullet in class.access.base.
Tested x86_64-pc-linux-gnu, applied to trunk.
2009-01-16 Jason Merrill <jason@redhat.com>
PR c++/38579
* search.c (protected_accessible_p): N doesn't vary.
* g++.dg/conversion/access1.C: New test.
Index: cp/search.c
===================================================================
*** cp/search.c (revision 143437)
--- cp/search.c (working copy)
*************** protected_accessible_p (tree decl, tree
*** 721,740 ****
m as a member of N is protected, and the reference occurs in a
member or friend of class N, or in a member or friend of a
! class P derived from N, where m as a member of P is private or
! protected.
! Here DERIVED is a possible P and DECL is m. accessible_p will
! iterate over various values of N, but the access to m in DERIVED
! does not change.
!
! Note that I believe that the passage above is wrong, and should read
! "...is private or protected or public"; otherwise you get bizarre results
! whereby a public using-decl can prevent you from accessing a protected
! member of a base. (jason 2000/02/28) */
! /* If DERIVED isn't derived from m's class, then it can't be a P. */
! if (!DERIVED_FROM_P (context_for_name_lookup (decl), derived))
return 0;
access = access_in_type (derived, decl);
--- 721,733 ----
m as a member of N is protected, and the reference occurs in a
member or friend of class N, or in a member or friend of a
! class P derived from N, where m as a member of P is public, private
! or protected.
! Here DERIVED is a possible P, DECL is m and BINFO_TYPE (binfo) is N. */
! /* If DERIVED isn't derived from N, then it can't be a P. */
! if (!DERIVED_FROM_P (BINFO_TYPE (binfo), derived))
return 0;
access = access_in_type (derived, decl);
Index: testsuite/g++.dg/conversion/access1.C
===================================================================
*** testsuite/g++.dg/conversion/access1.C (revision 0)
--- testsuite/g++.dg/conversion/access1.C (revision 0)
***************
*** 0 ****
--- 1,25 ----
+ // PR c++/38579
+
+ struct P
+ {
+ protected:
+ P() {}
+ P(const P&) {}
+ };
+
+ struct B : protected P
+ {
+ B() {}
+ };
+
+ struct C : public P
+ {
+ // C can access P's copy ctor, but can't convert b to const P&.
+ C(const B& b) : P(b) {} // { dg-error "inaccessible base" }
+ };
+
+ void foo()
+ {
+ B b;
+ C c(b);
+ }