diff options
author | Jason Merrill <jason@redhat.com> | 2004-06-24 16:07:23 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2004-06-24 16:07:23 -0400 |
commit | 3db4a9b428b760809fdff522272b95c378949e9b (patch) | |
tree | f23d2ae011d1f97ca7d6a6cfbab603fd1b9babf1 | |
parent | de7c79cc7771f311aa451103162436077aa1699a (diff) | |
download | gcc-3db4a9b428b760809fdff522272b95c378949e9b.zip gcc-3db4a9b428b760809fdff522272b95c378949e9b.tar.gz gcc-3db4a9b428b760809fdff522272b95c378949e9b.tar.bz2 |
re PR tree-optimization/16115 (double-destruction problem with argument passing via temporary (breaks auto_ptr))
PR c++/16115
* decl.c (grokparms): Give the PARM_DECL reference type if the
parameter is passed by invisible reference.
From-SVN: r83609
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/call1.C | 35 |
3 files changed, 49 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 678e0ca..fee6c9a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-06-24 Jason Merrill <jason@redhat.com> + + PR c++/16115 + * decl.c (grokparms): Give the PARM_DECL reference type if the + parameter is passed by invisible reference. + 2004-06-24 Andreas Schwab <schwab@suse.de> * cp-tree.h (enum cp_storage_class): Remove trailing comma. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e986cb7..2798440 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8224,6 +8224,13 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms) if (type != error_mark_node) { + /* If this type is passed by invisible reference, make the PARM_DECL + reflect that so that alias analysis knows that the actual object + is external to the function. */ + if (TREE_ADDRESSABLE (type)) + decl = build_decl (PARM_DECL, DECL_NAME (decl), + build_reference_type (type)); + /* Top-level qualifiers on the parameters are ignored for function types. */ type = cp_build_qualified_type (type, 0); @@ -8258,7 +8265,7 @@ grokparms (cp_parameter_declarator *first_parm, tree *parms) } if (!any_error && init) - init = check_default_argument (decl, init); + init = check_default_argument (type, init); else init = NULL_TREE; } diff --git a/gcc/testsuite/g++.dg/init/call1.C b/gcc/testsuite/g++.dg/init/call1.C new file mode 100644 index 0000000..15b700fc --- /dev/null +++ b/gcc/testsuite/g++.dg/init/call1.C @@ -0,0 +1,35 @@ +// Bug c++/16115 +// { dg-do run } + +extern "C" void abort(); + +int count = 0; + +struct T { + T() { count++; } + T(const T&) { count++; } + ~T() { if (count==0) abort(); --count; } +}; + +struct auto_ptr { + T* p; + + auto_ptr(T* __p) : p(__p) { } + ~auto_ptr() { delete p; } + + T* release() { + T* t = p; + p = 0; + return t; + } +}; + +void destroy (auto_ptr a) { + delete a.release(); +} + + +int main () +{ + destroy (new T); +} |