summaryrefslogtreecommitdiff
path: root/gcc/cp/method.c
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-04 17:45:16 +0000
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-04 17:45:16 +0000
commiteca827d5f155efda81059560a4dae0309f437af9 (patch)
treeb1c370ce6f0a73b8b6bd72c7bbb2a3dc0e3f62ff /gcc/cp/method.c
parent75511ae89db8fa621b6745df387e4b66da4db714 (diff)
downloadgcc-eca827d5f155efda81059560a4dae0309f437af9.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97557 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/method.c')
-rw-r--r--gcc/cp/method.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 70d664283bb..9036f64c802 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -470,10 +470,27 @@ use_thunk (tree thunk_fndecl, bool emit_p)
finish_expr_stmt (t);
else
{
- t = force_target_expr (TREE_TYPE (t), t);
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);
}