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]

(C++) patch to build_m_component_ref


We weren't propagating cv-quals from the object to the reference
expression.  Testcase below.

Tested on i686-pc-linux-gnu.

2000-12-15  Jason Merrill  <jason@redhat.com>

	* typeck2.c (build_m_component_ref): Propagate quals from datum.

*** typeck2.c.~1~	Fri Dec 15 14:29:08 2000
--- typeck2.c	Fri Dec 15 14:29:15 2000
*************** build_m_component_ref (datum, component)
*** 1077,1098 ****
       tree datum, component;
  {
    tree type;
!   tree objtype = TREE_TYPE (datum);
!   tree rettype;
    tree binfo;
  
    if (processing_template_decl)
      return build_min_nt (DOTSTAR_EXPR, datum, component);
  
    if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
      {
        type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component)));
!       rettype = type;
      }
    else
      {
        type = TREE_TYPE (TREE_TYPE (component));
!       rettype = TREE_TYPE (type);
      }
  
    if (datum == error_mark_node || component == error_mark_node)
--- 1077,1102 ----
       tree datum, component;
  {
    tree type;
!   tree objtype;
!   tree field_type;
!   int type_quals;
    tree binfo;
  
    if (processing_template_decl)
      return build_min_nt (DOTSTAR_EXPR, datum, component);
  
+   datum = decay_conversion (datum);
+   objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));  
+ 
    if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
      {
        type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component)));
!       field_type = type;
      }
    else
      {
        type = TREE_TYPE (TREE_TYPE (component));
!       field_type = TREE_TYPE (type);
      }
  
    if (datum == error_mark_node || component == error_mark_node)
*************** build_m_component_ref (datum, component)
*** 1104,1113 ****
        return error_mark_node;
      }
  
-   if (TREE_CODE (objtype) == REFERENCE_TYPE)
-     objtype = TREE_TYPE (objtype);
-   objtype = TYPE_MAIN_VARIANT (objtype);
- 
    if (! IS_AGGR_TYPE (objtype))
      {
        cp_error ("cannot apply member pointer `%E' to `%E'", component, datum);
--- 1108,1113 ----
*************** build_m_component_ref (datum, component)
*** 1125,1131 ****
    else if (binfo == error_mark_node)
      return error_mark_node;
  
!   component = build (OFFSET_REF, rettype, datum, component);
    if (TREE_CODE (type) == OFFSET_TYPE)
      component = resolve_offset_ref (component);
    return component;
--- 1125,1148 ----
    else if (binfo == error_mark_node)
      return error_mark_node;
  
!   /* Compute the type of the field, as described in [expr.ref].  */
!   type_quals = TYPE_UNQUALIFIED;
!   if (TREE_CODE (field_type) == REFERENCE_TYPE)
!     /* The standard says that the type of the result should be the
!        type referred to by the reference.  But for now, at least, we
!        do the conversion from reference type later.  */
!     ;
!   else
!     {
!       type_quals = (CP_TYPE_QUALS (field_type)  
! 		    | CP_TYPE_QUALS (TREE_TYPE (datum)));
! 
!       /* There's no such thing as a mutable pointer-to-member, so we don't
! 	 need to deal with that here like we do in build_component_ref.  */
!       field_type = cp_build_qualified_type (field_type, type_quals);
!     }
! 
!   component = build (OFFSET_REF, field_type, datum, component);
    if (TREE_CODE (type) == OFFSET_TYPE)
      component = resolve_offset_ref (component);
    return component;

// Test that const-correctness is observed when using pointers-to-members.

struct A {
  int f () { return 1; }
  int f () const { return 0; }
};

struct B {
  A a;
  B() { }
};

int main ()
{
  A B::*bm = &B::a;
  const B b;
  return (b.*bm).f ();
}

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