diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/c-decl.c | 4 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/new26.C | 44 | ||||
-rw-r--r-- | gcc/tree-inline.c | 24 | ||||
-rw-r--r-- | gcc/tree.h | 14 |
8 files changed, 108 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8099410..a4c939c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +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> PR debug/34484 diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 9237a75..860b337 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -1,6 +1,7 @@ /* Process declarations and variables for C compiler. 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. @@ -1740,6 +1741,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); TREE_READONLY (newdecl) |= TREE_READONLY (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_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl); } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 030232b..91909a1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +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> PR c++/33819 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 11a5c47..4b2a55f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1,6 +1,7 @@ /* Process declarations and variables for C++ compiler. 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) This file is part of GCC. @@ -1804,6 +1805,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); TREE_NOTHROW (newdecl) |= TREE_NOTHROW (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); /* Keep the old RTL. */ COPY_DECL_RTL (olddecl, newdecl); @@ -9761,7 +9763,10 @@ grok_op_properties (tree decl, bool complain) } 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) TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl)); else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3e7ee20..cc3ec9c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +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> PR middle-end/34801 diff --git a/gcc/testsuite/g++.dg/init/new26.C b/gcc/testsuite/g++.dg/init/new26.C new file mode 100644 index 0000000..541de30 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/new26.C @@ -0,0 +1,44 @@ +// 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; +} 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 @@ -1,6 +1,7 @@ /* Front-end tree definitions for GNU compiler. 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. @@ -3241,6 +3242,12 @@ struct tree_decl_non_common GTY(()) not an alias. */ #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 than once. */ #define DECL_IS_RETURNS_TWICE(NODE) \ @@ -3345,16 +3352,17 @@ struct tree_function_decl GTY(()) unsigned novops_flag : 1; unsigned returns_twice_flag : 1; unsigned malloc_flag : 1; + unsigned operator_new_flag : 1; unsigned pure_flag : 1; unsigned declared_inline_flag : 1; unsigned regdecl_flag : 1; - unsigned inline_flag : 1; + unsigned inline_flag : 1; unsigned no_instrument_function_entry_exit : 1; unsigned no_limit_stack : 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.) */ |