From: Ian Lance Taylor Date: Fri, 18 Jan 2008 15:25:02 +0000 (+0000) Subject: re PR c++/33407 (C++ operator new and new expression do not change dynamic type) X-Git-Tag: releases/gcc-4.3.0~548 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ea193c21f060b7e7837138122b24c9d07f57d57;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8099410d1edc..a4c939c813ea 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2008-01-18 Ian Lance Taylor + + 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 PR debug/34484 diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 9237a75491a5..860b337fc958 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 030232b40e90..91909a1fb1ff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2008-01-18 Ian Lance Taylor + + 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 PR c++/33819 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 11a5c478fbe2..4b2a55fe11f6 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 3e7ee209b41f..cc3ec9c2a3bf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-01-18 Ian Lance Taylor + + PR c++/33407 + * g++.dg/init/new26.C: New test. + 2008-01-18 Richard Guenther 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 000000000000..541de3058e10 --- /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; ifunction_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.) */