This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
(C++) patch to build_m_component_ref
- To: gcc-patches at gcc dot gnu dot org
- Subject: (C++) patch to build_m_component_ref
- From: Jason Merrill <jason at redhat dot com>
- Date: 15 Dec 2000 14:43:16 +0000
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 ();
}