This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

C++ PATCH: PR 11345


This patch fixes PR 11345.  Tested on i686-pc-linux-gnu, applied on
the mainline and on the branch.  The key change is the
maybe_dummy_object bit -- we must not try to do bogus conversions.

The access8.C change makes the branch test more like the mainline
test, and was not applied on the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-07-06  Mark Mitchell  <mark@codesourcery.com>

	PR c++/11345
	* search.c (lookup_base_r): Remove is_non_public and
	within_current_scope parameters.  Remove other dead code.
	(lookup_base): Adjust call to lookup_base_r.
	(adjust_result_of_qualified_name_lookup): Improve comment.
	* semantics.c (finish_call_expr): Use maybe_dummy_object.

2003-07-06  Mark Mitchell  <mark@codesourcery.com>

	PR c++/11345
	* g++.old-deja/g++.jason/access8.C: New test.

Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.243.2.11
diff -c -5 -p -r1.243.2.11 search.c
*** cp/search.c	26 Jun 2003 01:05:39 -0000	1.243.2.11
--- cp/search.c	6 Jul 2003 21:53:34 -0000
*************** struct vbase_info 
*** 83,93 ****
  static int is_subobject_of_p PARAMS ((tree, tree, tree));
  static int is_subobject_of_p_1 PARAMS ((tree, tree, tree));
  static tree dfs_check_overlap PARAMS ((tree, void *));
  static tree dfs_no_overlap_yet PARAMS ((tree, void *));
  static base_kind lookup_base_r
! 	PARAMS ((tree, tree, base_access, int, int, int, tree *));
  static int dynamic_cast_base_recurse PARAMS ((tree, tree, int, tree *));
  static tree marked_pushdecls_p PARAMS ((tree, void *));
  static tree unmarked_pushdecls_p PARAMS ((tree, void *));
  static tree dfs_debug_unmarkedp PARAMS ((tree, void *));
  static tree dfs_debug_mark PARAMS ((tree, void *));
--- 83,93 ----
  static int is_subobject_of_p PARAMS ((tree, tree, tree));
  static int is_subobject_of_p_1 PARAMS ((tree, tree, tree));
  static tree dfs_check_overlap PARAMS ((tree, void *));
  static tree dfs_no_overlap_yet PARAMS ((tree, void *));
  static base_kind lookup_base_r
! 	PARAMS ((tree, tree, base_access, int, tree *));
  static int dynamic_cast_base_recurse PARAMS ((tree, tree, int, tree *));
  static tree marked_pushdecls_p PARAMS ((tree, void *));
  static tree unmarked_pushdecls_p PARAMS ((tree, void *));
  static tree dfs_debug_unmarkedp PARAMS ((tree, void *));
  static tree dfs_debug_mark PARAMS ((tree, void *));
*************** static int n_contexts_saved;
*** 162,208 ****
  #endif /* GATHER_STATISTICS */
  
  
  /* Worker for lookup_base.  BINFO is the binfo we are searching at,
     BASE is the RECORD_TYPE we are searching for.  ACCESS is the
!    required access checks.  WITHIN_CURRENT_SCOPE, IS_NON_PUBLIC and
!    IS_VIRTUAL indicate how BINFO was reached from the start of the
!    search.  WITHIN_CURRENT_SCOPE is true if we met the current scope,
!    or friend thereof (this allows us to determine whether a protected
!    base is accessible or not).  IS_NON_PUBLIC indicates whether BINFO
!    is accessible and IS_VIRTUAL indicates if it is morally virtual.
  
     If BINFO is of the required type, then *BINFO_PTR is examined to
     compare with any other instance of BASE we might have already
     discovered. *BINFO_PTR is initialized and a base_kind return value
     indicates what kind of base was located.
  
     Otherwise BINFO's bases are searched.  */
  
  static base_kind
! lookup_base_r (binfo, base, access, within_current_scope,
! 	       is_non_public, is_virtual, binfo_ptr)
       tree binfo, base;
       base_access access;
-      int within_current_scope;
-      int is_non_public;		/* inside a non-public part */
       int is_virtual;		/* inside a virtual part */
       tree *binfo_ptr;
  {
    int i;
    tree bases;
    base_kind found = bk_not_base;
    
-   if (access == ba_check
-       && !within_current_scope
-       && is_friend (BINFO_TYPE (binfo), current_scope ()))
-     {
-       /* Do not clear is_non_public here.  If A is a private base of B, A
- 	 is not allowed to convert a B* to an A*.  */
-       within_current_scope = 1;
-     }
-   
    if (same_type_p (BINFO_TYPE (binfo), base))
      {
        /* We have found a base. Check against what we have found
           already.  */
        found = bk_same_type;
--- 162,192 ----
  #endif /* GATHER_STATISTICS */
  
  
  /* Worker for lookup_base.  BINFO is the binfo we are searching at,
     BASE is the RECORD_TYPE we are searching for.  ACCESS is the
!    required access checks.  IS_VIRTUAL indicates if BINFO is morally
!    virtual.
  
     If BINFO is of the required type, then *BINFO_PTR is examined to
     compare with any other instance of BASE we might have already
     discovered. *BINFO_PTR is initialized and a base_kind return value
     indicates what kind of base was located.
  
     Otherwise BINFO's bases are searched.  */
  
  static base_kind
! lookup_base_r (binfo, base, access, is_virtual, binfo_ptr)
       tree binfo, base;
       base_access access;
       int is_virtual;		/* inside a virtual part */
       tree *binfo_ptr;
  {
    int i;
    tree bases;
    base_kind found = bk_not_base;
    
    if (same_type_p (BINFO_TYPE (binfo), base))
      {
        /* We have found a base. Check against what we have found
           already.  */
        found = bk_same_type;
*************** lookup_base_r (binfo, base, access, with
*** 230,280 ****
      return bk_not_base;
    
    for (i = TREE_VEC_LENGTH (bases); i--;)
      {
        tree base_binfo = TREE_VEC_ELT (bases, i);
-       int this_non_public = is_non_public;
-       int this_virtual = is_virtual;
        base_kind bk;
  
-       if (access <= ba_ignore)
- 	; /* no change */
-       else if (TREE_VIA_PUBLIC (base_binfo))
- 	; /* no change */
-       else if (access == ba_not_special)
- 	this_non_public = 1;
-       else if (TREE_VIA_PROTECTED (base_binfo) && within_current_scope)
- 	; /* no change */
-       else if (is_friend (BINFO_TYPE (binfo), current_scope ()))
- 	; /* no change */
-       else
- 	this_non_public = 1;
-       
-       if (TREE_VIA_VIRTUAL (base_binfo))
- 	this_virtual = 1;
-       
        bk = lookup_base_r (base_binfo, base,
! 		    	  access, within_current_scope,
! 			  this_non_public, this_virtual,
  			  binfo_ptr);
  
        switch (bk)
  	{
  	case bk_ambig:
  	  if (access != ba_any)
  	    return bk;
  	  found = bk;
  	  break;
  	  
- 	case bk_inaccessible:
- 	  if (found == bk_not_base)
- 	    found = bk;
- 	  my_friendly_assert (found == bk_via_virtual
- 			      || found == bk_inaccessible, 20010723);
- 	  
- 	  break;
- 	  
  	case bk_same_type:
  	  bk = bk_proper_base;
  	  /* FALLTHROUGH */
  	case bk_proper_base:
  	  my_friendly_assert (found == bk_not_base, 20010723);
--- 214,238 ----
      return bk_not_base;
    
    for (i = TREE_VEC_LENGTH (bases); i--;)
      {
        tree base_binfo = TREE_VEC_ELT (bases, i);
        base_kind bk;
  
        bk = lookup_base_r (base_binfo, base,
! 		    	  access,
! 			  is_virtual || TREE_VIA_VIRTUAL (base_binfo),
  			  binfo_ptr);
  
        switch (bk)
  	{
  	case bk_ambig:
  	  if (access != ba_any)
  	    return bk;
  	  found = bk;
  	  break;
  	  
  	case bk_same_type:
  	  bk = bk_proper_base;
  	  /* FALLTHROUGH */
  	case bk_proper_base:
  	  my_friendly_assert (found == bk_not_base, 20010723);
*************** lookup_base_r (binfo, base, access, with
*** 286,295 ****
--- 244,256 ----
  	    found = bk;
  	  break;
  	  
  	case bk_not_base:
  	  break;
+ 
+ 	default:
+ 	  abort ();
  	}
      }
    return found;
  }
  
*************** lookup_base (t, base, access, kind_ptr)
*** 331,342 ****
  
    /* Ensure that the types are instantiated.  */
    t = complete_type (TYPE_MAIN_VARIANT (t));
    base = complete_type (TYPE_MAIN_VARIANT (base));
    
!   bk = lookup_base_r (t_binfo, base, access & ~ba_quiet,
! 		      0, 0, 0, &binfo);
  
    /* Check that the base is unambiguous and accessible.  */
    if (access != ba_any)
      switch (bk)
        {
--- 292,302 ----
  
    /* Ensure that the types are instantiated.  */
    t = complete_type (TYPE_MAIN_VARIANT (t));
    base = complete_type (TYPE_MAIN_VARIANT (base));
    
!   bk = lookup_base_r (t_binfo, base, access, 0, &binfo);
  
    /* Check that the base is unambiguous and accessible.  */
    if (access != ba_any)
      switch (bk)
        {
*************** adjust_result_of_qualified_name_lookup (
*** 1860,1873 ****
    if (BASELINK_P (decl) 
        && DERIVED_FROM_P (qualifying_class, context_class))
      {
        tree base;
  
!       /* Look for the QUALIFYING_CLASS as a base of the
! 	 CONTEXT_CLASS.  If QUALIFYING_CLASS is ambiguous, we cannot
! 	 be sure yet than an error has occurred; perhaps the function
! 	 chosen by overload resolution will be static.  */
        base = lookup_base (context_class, qualifying_class,
  			  ba_ignore | ba_quiet, NULL);
        if (base)
  	{
  	  BASELINK_ACCESS_BINFO (decl) = base;
--- 1820,1834 ----
    if (BASELINK_P (decl) 
        && DERIVED_FROM_P (qualifying_class, context_class))
      {
        tree base;
  
!       /* Look for the QUALIFYING_CLASS as a base of the CONTEXT_CLASS.
! 	 Because we do not yet know which function will be chosen by
! 	 overload resolution, we cannot yet check either accessibility
! 	 or ambiguity -- in either case, the choice of a static member
! 	 function might make the usage valid.  */
        base = lookup_base (context_class, qualifying_class,
  			  ba_ignore | ba_quiet, NULL);
        if (base)
  	{
  	  BASELINK_ACCESS_BINFO (decl) = base;
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.282.4.5
diff -c -5 -p -r1.282.4.5 semantics.c
*** cp/semantics.c	20 Jun 2003 03:06:28 -0000	1.282.4.5
--- cp/semantics.c	6 Jul 2003 21:53:34 -0000
*************** finish_call_expr (tree fn, tree args, bo
*** 1271,1281 ****
  	to `B'.  We believe it refers to `B'.  */
        if (current_class_type 
  	  && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
  			     current_class_type)
  	  && current_class_ref)
! 	object = current_class_ref;
        else
  	{
  	  tree representative_fn;
  
  	  representative_fn = BASELINK_FUNCTIONS (fn);
--- 1271,1282 ----
  	to `B'.  We believe it refers to `B'.  */
        if (current_class_type 
  	  && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
  			     current_class_type)
  	  && current_class_ref)
! 	object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
! 				     NULL);
        else
  	{
  	  tree representative_fn;
  
  	  representative_fn = BASELINK_FUNCTIONS (fn);
Index: testsuite/g++.old-deja/g++.jason/access8.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.jason/access8.C,v
retrieving revision 1.4.20.1
diff -c -5 -p -r1.4.20.1 access8.C
*** testsuite/g++.old-deja/g++.jason/access8.C	26 Jun 2003 01:05:45 -0000	1.4.20.1
--- testsuite/g++.old-deja/g++.jason/access8.C	6 Jul 2003 21:53:39 -0000
*************** protected:
*** 18,28 ****
  class top_t : protected mel {
  public:
          void myf(int);
  };
  
! void inh::myf(int i) { // ERROR - inaccessible
          a = i;
  }
  
  void top_t::myf(int i) {
          inh::myf(i);		// ERROR - cannot convert to inh
--- 18,28 ----
  class top_t : protected mel {
  public:
          void myf(int);
  };
  
! void inh::myf(int i) {
          a = i;
  }
  
  void top_t::myf(int i) {
          inh::myf(i);		// ERROR - cannot convert to inh


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