Commit 44ba4c4e by Jason Merrill Committed by Jason Merrill

re PR c++/31074 (Reference casting involving multiple inheritance produces bad pointer)

        PR c++/31074
        * call.c (reference_binding): Add c_cast_p parm.  If true,
        add quals to TO as needed to make it reference-compatible.

From-SVN: r123805
parent 9a7b07c6
2007-04-13 Jason Merrill <jason@redhat.com>
PR c++/31074
* call.c (reference_binding): Add c_cast_p parm. If true,
add quals to TO as needed to make it reference-compatible.
2007-04-11 Jan Hubicka <jh@suse.cz> 2007-04-11 Jan Hubicka <jh@suse.cz>
* cp/class.c (convert_to_base_statically): Fold produced tree; verify * cp/class.c (convert_to_base_statically): Fold produced tree; verify
......
...@@ -173,7 +173,7 @@ static struct z_candidate *add_function_candidate ...@@ -173,7 +173,7 @@ static struct z_candidate *add_function_candidate
(struct z_candidate **, tree, tree, tree, tree, tree, int); (struct z_candidate **, tree, tree, tree, tree, tree, int);
static conversion *implicit_conversion (tree, tree, tree, bool, int); static conversion *implicit_conversion (tree, tree, tree, bool, int);
static conversion *standard_conversion (tree, tree, tree, bool, int); static conversion *standard_conversion (tree, tree, tree, bool, int);
static conversion *reference_binding (tree, tree, tree, int); static conversion *reference_binding (tree, tree, tree, bool, int);
static conversion *build_conv (conversion_kind, tree, conversion *); static conversion *build_conv (conversion_kind, tree, conversion *);
static bool is_subseq (conversion *, conversion *); static bool is_subseq (conversion *, conversion *);
static tree maybe_handle_ref_bind (conversion **); static tree maybe_handle_ref_bind (conversion **);
...@@ -1105,10 +1105,11 @@ direct_reference_binding (tree type, conversion *conv) ...@@ -1105,10 +1105,11 @@ direct_reference_binding (tree type, conversion *conv)
purposes of reference binding. For lvalue binding, either pass a purposes of reference binding. For lvalue binding, either pass a
reference type to FROM or an lvalue expression to EXPR. If the reference type to FROM or an lvalue expression to EXPR. If the
reference will be bound to a temporary, NEED_TEMPORARY_P is set for reference will be bound to a temporary, NEED_TEMPORARY_P is set for
the conversion returned. */ the conversion returned. If C_CAST_P is true, this
conversion is coming from a C-style cast. */
static conversion * static conversion *
reference_binding (tree rto, tree rfrom, tree expr, int flags) reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
{ {
conversion *conv = NULL; conversion *conv = NULL;
tree to = TREE_TYPE (rto); tree to = TREE_TYPE (rto);
...@@ -1138,6 +1139,11 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags) ...@@ -1138,6 +1139,11 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
reference compatible. We have do do this after stripping reference compatible. We have do do this after stripping
references from FROM. */ references from FROM. */
related_p = reference_related_p (to, from); related_p = reference_related_p (to, from);
/* If this is a C cast, first convert to an appropriately qualified
type, so that we can later do a const_cast to the desired type. */
if (related_p && c_cast_p
&& !at_least_as_qualified_p (to, from))
to = build_qualified_type (to, cp_type_quals (from));
compatible_p = reference_compatible_p (to, from); compatible_p = reference_compatible_p (to, from);
if (lvalue_p && compatible_p) if (lvalue_p && compatible_p)
...@@ -1247,7 +1253,7 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags) ...@@ -1247,7 +1253,7 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
if (related_p && !at_least_as_qualified_p (to, from)) if (related_p && !at_least_as_qualified_p (to, from))
return NULL; return NULL;
conv = implicit_conversion (to, from, expr, /*c_cast_p=*/false, conv = implicit_conversion (to, from, expr, c_cast_p,
flags); flags);
if (!conv) if (!conv)
return NULL; return NULL;
...@@ -1277,7 +1283,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, ...@@ -1277,7 +1283,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
return NULL; return NULL;
if (TREE_CODE (to) == REFERENCE_TYPE) if (TREE_CODE (to) == REFERENCE_TYPE)
conv = reference_binding (to, from, expr, flags); conv = reference_binding (to, from, expr, c_cast_p, flags);
else else
conv = standard_conversion (to, from, expr, c_cast_p, flags); conv = standard_conversion (to, from, expr, c_cast_p, flags);
...@@ -6618,7 +6624,8 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) ...@@ -6618,7 +6624,8 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
/* Get the high-water mark for the CONVERSION_OBSTACK. */ /* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0); p = conversion_obstack_alloc (0);
conv = reference_binding (type, TREE_TYPE (expr), expr, LOOKUP_NORMAL); conv = reference_binding (type, TREE_TYPE (expr), expr, /*c_cast_p=*/false,
LOOKUP_NORMAL);
if (!conv || conv->bad_p) if (!conv || conv->bad_p)
{ {
if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST) if (!(TYPE_QUALS (TREE_TYPE (type)) & TYPE_QUAL_CONST)
......
2007-04-13 Jason Merrill <jason@redhat.com>
PR c++/31074
* conv3.C: New test.
2007-04-13 Mike Stump <mrs@apple.com> 2007-04-13 Mike Stump <mrs@apple.com>
* obj-c++.dg/stubify-1.mm: Only run on powerpc. * obj-c++.dg/stubify-1.mm: Only run on powerpc.
// PR 31074
// Bug: The reference cast wasn't finding the desired static_cast followed by
// const_cast interpretation.
struct Shape
{
Shape() {}
virtual ~Shape() {}
};
struct Loop
{
Loop() {}
virtual ~Loop() {}
virtual void func() {}
};
struct Rect :
public Shape,
public Loop
{
Rect() {}
virtual ~Rect() {}
};
int main ()
{
const Rect* rect = new Rect();
Loop &l = ((Loop&)(*rect));
return (&l != (const Loop *)rect);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment