diff options
author | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-04 17:45:16 +0000 |
---|---|---|
committer | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-04-04 17:45:16 +0000 |
commit | eca827d5f155efda81059560a4dae0309f437af9 (patch) | |
tree | b1c370ce6f0a73b8b6bd72c7bbb2a3dc0e3f62ff /gcc/cp/method.c | |
parent | 75511ae89db8fa621b6745df387e4b66da4db714 (diff) | |
download | gcc-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.c | 23 |
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); } |