Commit 1ea193c2 by Ian Lance Taylor Committed by Ian Lance Taylor

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
parent c27fb14b
2008-01-18 Ian Lance Taylor <iant@google.com>
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.
2008-01-18 Uros Bizjak <ubizjak@gmail.com> 2008-01-18 Uros Bizjak <ubizjak@gmail.com>
PR debug/34484 PR debug/34484
......
/* Process declarations and variables for C compiler. /* Process declarations and variables for C compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -1740,6 +1741,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) ...@@ -1740,6 +1741,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl); DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl); DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl); DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl);
} }
......
2008-01-18 Ian Lance Taylor <iant@google.com>
PR c++/33407
* 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.
2008-01-16 Richard Guenther <rguenther@suse.de> 2008-01-16 Richard Guenther <rguenther@suse.de>
PR c++/33819 PR c++/33819
......
/* Process declarations and variables for C++ compiler. /* Process declarations and variables for C++ compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC. This file is part of GCC.
...@@ -1804,6 +1805,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) ...@@ -1804,6 +1805,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
TREE_NOTHROW (newdecl) |= TREE_NOTHROW (olddecl); TREE_NOTHROW (newdecl) |= TREE_NOTHROW (olddecl);
DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl); DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl); DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
/* Keep the old RTL. */ /* Keep the old RTL. */
COPY_DECL_RTL (olddecl, newdecl); COPY_DECL_RTL (olddecl, newdecl);
...@@ -9761,7 +9763,10 @@ grok_op_properties (tree decl, bool complain) ...@@ -9761,7 +9763,10 @@ grok_op_properties (tree decl, bool complain)
} }
if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR) if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR)
{
TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl)); TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
DECL_IS_OPERATOR_NEW (decl) = 1;
}
else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR) else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl)); TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
else else
......
2008-01-18 Ian Lance Taylor <iant@google.com>
PR c++/33407
* g++.dg/init/new26.C: New test.
2008-01-18 Richard Guenther <rguenther@suse.de> 2008-01-18 Richard Guenther <rguenther@suse.de>
PR middle-end/34801 PR middle-end/34801
// PR c++/33407
// { dg-do run }
// { dg-options "-O2 -fstrict-aliasing" }
extern "C" void * malloc(__SIZE_TYPE__);
extern "C" void abort(void);
void *p;
void __attribute__((noinline)) init(void)
{
p = malloc(4);
}
inline void *operator new(__SIZE_TYPE__)
{
return p;
}
inline void operator delete (void*) {}
int * __attribute__((noinline)) doit(int n)
{
float *q;
int *r;
for (int i=0; i<n; ++i)
{
q = new float;
*q = 1.0;
delete q;
r = new int;
*r = 1;
}
return r;
}
int main()
{
init();
if (*doit(1) != 1)
abort();
return 0;
}
...@@ -2567,7 +2567,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data) ...@@ -2567,7 +2567,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
{ {
copy_body_data *id; copy_body_data *id;
tree t; tree t;
tree use_retvar; tree retvar, use_retvar;
tree fn; tree fn;
struct pointer_map_t *st; struct pointer_map_t *st;
tree return_slot; tree return_slot;
...@@ -2769,10 +2769,28 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data) ...@@ -2769,10 +2769,28 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
else else
modify_dest = NULL; 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 the return variable for the function. */
declare_return_variable (id, return_slot, retvar = declare_return_variable (id, return_slot,
modify_dest, &use_retvar); 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 /* This is it. Duplicate the callee body. Assume callee is
pre-gimplified. Note that we must not alter the caller pre-gimplified. Note that we must not alter the caller
function in any way before this point, as this CALL_EXPR may be function in any way before this point, as this CALL_EXPR may be
......
/* Front-end tree definitions for GNU compiler. /* Front-end tree definitions for GNU compiler.
Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -3241,6 +3242,12 @@ struct tree_decl_non_common GTY(()) ...@@ -3241,6 +3242,12 @@ struct tree_decl_non_common GTY(())
not an alias. */ not an alias. */
#define DECL_IS_MALLOC(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.malloc_flag) #define DECL_IS_MALLOC(NODE) (FUNCTION_DECL_CHECK (NODE)->function_decl.malloc_flag)
/* Nonzero in a FUNCTION_DECL means this function should be treated as
C++ operator new, meaning that it returns a pointer for which we
should not use type based aliasing. */
#define DECL_IS_OPERATOR_NEW(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.operator_new_flag)
/* Nonzero in a FUNCTION_DECL means this function may return more /* Nonzero in a FUNCTION_DECL means this function may return more
than once. */ than once. */
#define DECL_IS_RETURNS_TWICE(NODE) \ #define DECL_IS_RETURNS_TWICE(NODE) \
...@@ -3345,16 +3352,17 @@ struct tree_function_decl GTY(()) ...@@ -3345,16 +3352,17 @@ struct tree_function_decl GTY(())
unsigned novops_flag : 1; unsigned novops_flag : 1;
unsigned returns_twice_flag : 1; unsigned returns_twice_flag : 1;
unsigned malloc_flag : 1; unsigned malloc_flag : 1;
unsigned operator_new_flag : 1;
unsigned pure_flag : 1; unsigned pure_flag : 1;
unsigned declared_inline_flag : 1; unsigned declared_inline_flag : 1;
unsigned regdecl_flag : 1; unsigned regdecl_flag : 1;
unsigned inline_flag : 1;
unsigned inline_flag : 1;
unsigned no_instrument_function_entry_exit : 1; unsigned no_instrument_function_entry_exit : 1;
unsigned no_limit_stack : 1; unsigned no_limit_stack : 1;
unsigned disregard_inline_limits : 1; unsigned disregard_inline_limits : 1;
/* 5 bits left */ /* 4 bits left */
}; };
/* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */ /* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */
......
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