Commit 38a37714 by Nathan Sidwell Committed by Nathan Sidwell

re PR c++/20746 ([4.0 only] Incorrect return value for covariant return function…

re PR c++/20746 ([4.0 only] Incorrect return value for covariant return function returning null ptr)

cp:
	PR c++/20746
	* method.c (use_thunk): Protect covariant pointer return
	adjustments from NULL pointers.
testsuite:
	PR c++/20746
	* g++.dg/abi/covariant5.C: New.

From-SVN: r97557
parent 6d6f2d08
2005-04-04 Nathan Sidwell <nathan@codesourcery.com>
PR c++/20746
* method.c (use_thunk): Protect covariant pointer return
adjustments from NULL pointers.
2005-04-04 Jan Hubicka <jh@suse.cz> 2005-04-04 Jan Hubicka <jh@suse.cz>
* decl2.c (finish_objects): Revert my previous patch. * decl2.c (finish_objects): Revert my previous patch.
......
...@@ -470,10 +470,27 @@ use_thunk (tree thunk_fndecl, bool emit_p) ...@@ -470,10 +470,27 @@ use_thunk (tree thunk_fndecl, bool emit_p)
finish_expr_stmt (t); finish_expr_stmt (t);
else else
{ {
t = force_target_expr (TREE_TYPE (t), t);
if (!this_adjusting) if (!this_adjusting)
t = thunk_adjust (t, /*this_adjusting=*/0, {
fixed_offset, virtual_offset); tree cond = NULL_TREE;
if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
{
/* If the return type is a pointer, we need to
protect against NULL. We know there will be an
adjustment, because that's why we're emitting a
thunk. */
t = save_expr (t);
cond = cp_convert (boolean_type_node, t);
}
t = thunk_adjust (t, /*this_adjusting=*/0,
fixed_offset, virtual_offset);
if (cond)
t = build3 (COND_EXPR, TREE_TYPE (t), cond, t,
cp_convert (TREE_TYPE (t), integer_zero_node));
}
t = force_target_expr (TREE_TYPE (t), t);
finish_return_stmt (t); finish_return_stmt (t);
} }
......
2005-04-04 Nathan Sidwell <nathan@codesourcery.com> 2005-04-04 Nathan Sidwell <nathan@codesourcery.com>
PR c++/20746
* g++.dg/abi/covariant5.C: New.
PR debug/20505 PR debug/20505
* g++.dg/debug/const2.C: New. * g++.dg/debug/const2.C: New.
......
// Copyright (C) 2005 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 4 Apr 2005 <nathan@codesourcery.com>
// { dg-do run }
// PR 20746: Covariant return pointer could be null.
// Origin: yanliu@ca.ibm.com
// nathan@codesourcery.com
struct A {
virtual void One ();
};
struct B {
virtual B *Two ();
virtual B &Three ();
};
struct C : A, B
{
virtual C *Two ();
virtual C &Three ();
};
void A::One () {}
B *B::Two() {return this;}
B &B::Three() {return *this;}
C *C::Two () {return 0;}
C &C::Three () {return *(C *)0;}
B *Foo (B *b)
{
return b->Two ();
}
B &Bar (B *b)
{
return b->Three ();
}
int main ()
{
C c;
/* We should not adjust a null pointer. */
if (Foo (&c))
return 1;
/* But we should adjust a (bogus) null reference. */
if (!&Bar (&c))
return 2;
return 0;
}
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