aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2025-11-07 10:15:36 +0100
committerRichard Biener <rguenther@suse.de>2025-11-07 12:42:43 +0100
commit59e688be49a929daaa6f44f2a0bfff33e789e66b (patch)
treeee68d005928443af3cfc987605b4c0d99540cc96
parent7197d8062fddc26c05c0da0bbfcd4128de788e34 (diff)
downloadgcc-59e688be49a929daaa6f44f2a0bfff33e789e66b.zip
gcc-59e688be49a929daaa6f44f2a0bfff33e789e66b.tar.gz
gcc-59e688be49a929daaa6f44f2a0bfff33e789e66b.tar.bz2
tree-optimization/122589 - imm use iterator checking fallout
The following addresses the latent issue that gsi_replace_with_seq causes debug info to unnecessarily degrade and in this process break the new immediate use iterator sanity checking. In particular gsi_remove has side-effects on debug stmts even when operating in non-permanent operation. But as we are operating on a sequence not in the IL here this should be avoided. Re-factoring gsi_replace_with_seq to not rely on gsi_remove fulfills this. I've noticed gsi_split_seq_before has misleading documentation. Fixed thereby as well. PR tree-optimization/122589 PR middle-end/122594 * gimple-iterator.cc (gsi_replace_with_seq): Instead of removing the last stmt from the sequence with gsi_remove, split it using gsi_split_seq_before. (gsi_split_seq_before): Fix bogus documentation. * g++.dg/torture/pr122589.C: New testcase.
-rw-r--r--gcc/gimple-iterator.cc14
-rw-r--r--gcc/testsuite/g++.dg/torture/pr122589.C22
2 files changed, 28 insertions, 8 deletions
diff --git a/gcc/gimple-iterator.cc b/gcc/gimple-iterator.cc
index 3af672b..741e5a5 100644
--- a/gcc/gimple-iterator.cc
+++ b/gcc/gimple-iterator.cc
@@ -389,8 +389,8 @@ gsi_set_stmt (gimple_stmt_iterator *gsi, gimple *stmt)
}
-/* Move all statements in the sequence before I to a new sequence.
- Return this new sequence. I is set to the head of the new list. */
+/* Move all statements in the sequence starting at I to a new sequence.
+ Set *PNEW_SEQ to this sequence. I is set to the head of the new list. */
void
gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq)
@@ -471,18 +471,16 @@ void
gsi_replace_with_seq (gimple_stmt_iterator *gsi, gimple_seq seq,
bool update_eh_info)
{
- gimple_stmt_iterator seqi;
- gimple *last;
if (gimple_seq_empty_p (seq))
{
gsi_remove (gsi, true);
return;
}
- seqi = gsi_last (seq);
- last = gsi_stmt (seqi);
- gsi_remove (&seqi, false);
+ gimple_seq tail;
+ gimple_stmt_iterator lasti = gsi_last (seq);
+ gsi_split_seq_before (&lasti, &tail);
gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
- gsi_replace (gsi, last, update_eh_info);
+ gsi_replace (gsi, gsi_stmt (lasti), update_eh_info);
}
diff --git a/gcc/testsuite/g++.dg/torture/pr122589.C b/gcc/testsuite/g++.dg/torture/pr122589.C
new file mode 100644
index 0000000..ac441a0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr122589.C
@@ -0,0 +1,22 @@
+// { dg-do compile }
+// { dg-additional-options "-g" }
+
+struct QPointF {
+ QPointF(double xpos, double ypos) : xp(xpos), yp(ypos) {}
+ double xp;
+ double yp;
+};
+double xp, yp, w, h;
+struct QRectF {
+ QRectF(QPointF, int);
+ QPointF center() { return QPointF(xp + w / 2, yp + h / 2); }
+};
+void clientArea(QPointF &);
+int workspace_size;
+void workspace() {
+ QRectF geom(QPointF(0, 0), workspace_size);
+ xp = 0 - w / 2;
+ yp = -h;
+ QPointF __trans_tmp_2 = geom.center();
+ clientArea(__trans_tmp_2);
+}