diff options
author | Richard Guenther <rguenther@suse.de> | 2009-11-28 19:11:22 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2009-11-28 19:11:22 +0000 |
commit | f1c19648079168df5e3bf8ab7cee3a15f9203dc4 (patch) | |
tree | 94b97fb1416e57dbc696388eb5687ca3e1482c24 /gcc | |
parent | c750c208706d56fb9b3b8e2badf44ec4b7f37058 (diff) | |
download | gcc-f1c19648079168df5e3bf8ab7cee3a15f9203dc4.zip gcc-f1c19648079168df5e3bf8ab7cee3a15f9203dc4.tar.gz gcc-f1c19648079168df5e3bf8ab7cee3a15f9203dc4.tar.bz2 |
re PR middle-end/42183 (internal compiler error: verify_stmts failed)
2009-11-28 Richard Guenther <rguenther@suse.de>
PR tree-optimization/42183
* tree-nrv.c (tree_nrv): Bail out if the RESULT_DECL has its
address taken. Merge the addressable state of the NRV
variable and the result instead of copying it.
* g++.dg/torture/pr42183.C: New testcase.
From-SVN: r154728
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr42183.C | 51 | ||||
-rw-r--r-- | gcc/tree-nrv.c | 10 |
4 files changed, 71 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 14101e6..e68cf95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-11-28 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/42183 + * tree-nrv.c (tree_nrv): Bail out if the RESULT_DECL has its + address taken. Merge the addressable state of the NRV + variable and the result instead of copying it. + 2009-11-28 Jakub Jelinek <jakub@redhat.com> * matrix-reorg.c (analyze_matrix_allocation_site): Remove unused diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 16f2741..1c3e6f91 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-11-28 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/42183 + * g++.dg/torture/pr42183.C: New testcase. + 2009-11-28 Kai Tietz <kai.tietz@onevision.com> * gcc.dg/lto/20081210-1_0.c (uintptr_t): Use for diff --git a/gcc/testsuite/g++.dg/torture/pr42183.C b/gcc/testsuite/g++.dg/torture/pr42183.C new file mode 100644 index 0000000..375b37f --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr42183.C @@ -0,0 +1,51 @@ +// { dg-do compile } + +class IntSize { +public: + IntSize(int width, int height) : m_width(width), m_height(height) { } + int m_width, m_height; +}; +class IntPoint { +public: + IntPoint(int x, int y) : m_x(x), m_y(y) { } + int m_x, m_y; +}; +class IntRect { +public: + IntRect(int x, int y, int width, int height) + : m_location(IntPoint(x, y)), m_size(IntSize(width, height)) { } + void intersect(const IntRect&); + IntPoint m_location; + IntSize m_size; +}; +inline IntRect intersection(const IntRect& a, const IntRect& b) { + IntRect c = a; + c.intersect(b); + return c; +} +class RenderObject { +public: + int contentWidth() const { } + int contentHeight() const { } + virtual int xPos() const { } + virtual int yPos() const { } + virtual int paddingTop() const; + virtual int paddingLeft() const; + virtual int borderTop() const { } + virtual int borderLeft() const { } +}; +class RenderMenuList : public RenderObject { + virtual IntRect controlClipRect(int tx, int ty) const; + RenderObject* m_innerBlock; +}; +IntRect RenderMenuList::controlClipRect(int tx, int ty) const { + IntRect outerBox(tx + borderLeft() + paddingLeft(), + ty + borderTop() + paddingTop(), + contentWidth(), contentHeight()); + IntRect innerBox(tx + m_innerBlock->xPos() + m_innerBlock->paddingLeft(), + ty + m_innerBlock->yPos() + m_innerBlock->paddingTop(), + m_innerBlock->contentWidth(), + m_innerBlock->contentHeight()); + return intersection(outerBox, innerBox); +} + diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c index defa8de..a825a7a 100644 --- a/gcc/tree-nrv.c +++ b/gcc/tree-nrv.c @@ -129,6 +129,12 @@ tree_nrv (void) if (DECL_NAME (result)) return 0; + /* If the result has its address taken then it might be modified + by means not detected in the following loop. Bail out in this + case. */ + if (TREE_ADDRESSABLE (result)) + return 0; + /* Look through each block for assignments to the RESULT_DECL. */ FOR_EACH_BB (bb) { @@ -178,7 +184,7 @@ tree_nrv (void) || TREE_ADDRESSABLE (found) || DECL_ALIGN (found) > DECL_ALIGN (result) || !useless_type_conversion_p (result_type, - TREE_TYPE (found))) + TREE_TYPE (found))) return 0; } else if (gimple_has_lhs (stmt)) @@ -218,7 +224,7 @@ tree_nrv (void) DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (found); } - TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (found); + TREE_ADDRESSABLE (result) |= TREE_ADDRESSABLE (found); /* Now walk through the function changing all references to VAR to be RESULT. */ |