aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-11-28 19:11:22 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-11-28 19:11:22 +0000
commitf1c19648079168df5e3bf8ab7cee3a15f9203dc4 (patch)
tree94b97fb1416e57dbc696388eb5687ca3e1482c24 /gcc
parentc750c208706d56fb9b3b8e2badf44ec4b7f37058 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/torture/pr42183.C51
-rw-r--r--gcc/tree-nrv.c10
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. */