This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [bug] Inheritance and friend access control broken


>>>>> ĞAlexandreğ, Alexandre Oliva <oliva@dcc.unicamp.br> wrote:

Alexandre> Gabriel Dos Reis writes:
>> protected member field access control seems to be broken in EGCS-980205.

Alexandre> I don't think your example is correct.  Friendship is not transitive;
Alexandre> just because f() is friend of D, it doesn't mean it has any
Alexandre> priviledged access to B.  However, since B::j is a member of D
Alexandre> (inherited from B), f() can access it as such.


The FDIS says :

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
  ______________________________________________________________________

  11   Member access control                              [class.access]

  ______________________________________________________________________

1 A member of a class can be

  --private; that is, its name can be used only by members  and  friends
    of the class in which it is declared.

  --protected; that is, its name can be used only by members and friends
    of the class in which it is declared, and by members and friends  of
    classes derived from this class (see _class.protected_).

  --public;  that  is,  its  name  can  be  used anywhere without access
    restriction.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

And further in 11.5 there is this clause:


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

  11.5  Protected member access                        [class.protected] 
   
1 When  a  friend  or  a member function of a derived class references a
  protected nonstatic member of a base class, an access check applies in
  addition to those described earlier in clause _class.access_.4) Except
  when forming a pointer to member (_expr.unary.op_), the access must be
  through a pointer to, reference to, or object  of  the  derived  class
  itself  (or  any  class derived from that class) (_expr.ref_).  If the
  access is to form a pointer to member, the nested-name-specifier shall
  name the derived class (or any class derived from that class).  [Exam-
  ple:
  class B {
  protected: 
      int i;
      static int j; 
  };
      
  class D1 : public B {           
  };                  
   
  class D2 : public B {
      friend void fr(B*,D1*,D2*);
      void mem(B*,D1*);
  };
      
  _________________________
  4) This additional check does not apply to other members, e.g.  static
  data members or enumerator member constants. 
          
  void fr(B* pb, D1* p1, D2* p2)  
  {       
      pb->i = 1;                  // ill-formed
      p1->i = 2;                  // ill-formed
      p2->i = 3;                  // OK (access through a D2)
      p2->B::i = 4;               // OK (access through a D2, even though
      Z *pz;                      //     naming class is B)
      int B::* pmi_B = &B::i;     // ill-formed
      int B::* pmi_B2 = &D2::i;   // OK (type of &D2::i is int B::*)
      B::j = 5;                   // OK (because refers to static member)
      D2::j =6;                   // OK (because refers to static member)
  }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

As you can note B::j is accessible in fr(B*, D1*, D2*) which is a
friend of class D2 derived form class B. We are exactly in the
sirtuation I reported.



-- Gaby


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]