diff options
author | Ian Lance Taylor <iant@google.com> | 2008-01-18 15:25:02 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2008-01-18 15:25:02 +0000 |
commit | 1ea193c21f060b7e7837138122b24c9d07f57d57 (patch) | |
tree | f599ef6905608f93f1d83e94f82e9ef89480d5b3 /gcc/tree-inline.c | |
parent | c27fb14bda0b2c82c0fe8413e3e2f805c1d58975 (diff) | |
download | gcc-1ea193c21f060b7e7837138122b24c9d07f57d57.zip gcc-1ea193c21f060b7e7837138122b24c9d07f57d57.tar.gz gcc-1ea193c21f060b7e7837138122b24c9d07f57d57.tar.bz2 |
re PR c++/33407 (C++ operator new and new expression do not change dynamic type)
PR c++/33407
./: * tree.h (DECL_IS_OPERATOR_NEW): Define.
(struct tree_function_decl): Add new field operator_new_flag.
* tree-inline.c (expand_call_inline): When inlining a call to
operator new, force the return value to go into a variable, and
set DECL_NO_TBAA_P on that variable.
* c-decl.c (merge_decls): Merge DECL_IS_OPERATOR_NEW flag.
cp/:
* decl.c (duplicate_decls): Copy DECL_IS_OPERATOR_NEW flag.
(grok_op_properties): For NEW_EXPR and VEC_NEW_EXPR set
DECL_IS_OPERATOR_NEW flag.
testsuite/:
* g++.dg/init/new26.C: New test.
From-SVN: r131629
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 6ac367e..1fe0847 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2567,7 +2567,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data) { copy_body_data *id; tree t; - tree use_retvar; + tree retvar, use_retvar; tree fn; struct pointer_map_t *st; tree return_slot; @@ -2769,9 +2769,27 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data) else modify_dest = NULL; + /* If we are inlining a call to the C++ operator new, we don't want + to use type based alias analysis on the return value. Otherwise + we may get confused if the compiler sees that the inlined new + function returns a pointer which was just deleted. See bug + 33407. */ + if (DECL_IS_OPERATOR_NEW (fn)) + { + return_slot = NULL; + modify_dest = NULL; + } + /* Declare the return variable for the function. */ - declare_return_variable (id, return_slot, - modify_dest, &use_retvar); + retvar = declare_return_variable (id, return_slot, + modify_dest, &use_retvar); + + if (DECL_IS_OPERATOR_NEW (fn)) + { + gcc_assert (TREE_CODE (retvar) == VAR_DECL + && POINTER_TYPE_P (TREE_TYPE (retvar))); + DECL_NO_TBAA_P (retvar) = 1; + } /* This is it. Duplicate the callee body. Assume callee is pre-gimplified. Note that we must not alter the caller |