}
}
+static constexpr size_t verify_sequence_points_limit = 1024;
+
+/* Called from verify_sequence_points via walk_tree. */
+
+static tree
+verify_tree_lim_r (tree *tp, int *walk_subtrees, void *data)
+{
+ if (++*((size_t *) data) > verify_sequence_points_limit)
+ return integer_zero_node;
+
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+
+ return NULL_TREE;
+}
+
/* Try to warn for undefined behavior in EXPR due to missing sequence
points. */
void
verify_sequence_points (tree expr)
{
- struct tlist *before_sp = 0, *after_sp = 0;
+ tlist *before_sp = nullptr, *after_sp = nullptr;
+
+ /* verify_tree is highly recursive, and merge_tlist is O(n^2),
+ so we return early if the expression is too big. */
+ size_t n = 0;
+ if (walk_tree (&expr, verify_tree_lim_r, &n, nullptr))
+ return;
- warned_ids = 0;
- save_expr_cache = 0;
- if (tlist_firstobj == 0)
+ warned_ids = nullptr;
+ save_expr_cache = nullptr;
+ if (!tlist_firstobj)
{
gcc_obstack_init (&tlist_obstack);
tlist_firstobj = (char *) obstack_alloc (&tlist_obstack, 0);
}
- verify_tree (expr, &before_sp, &after_sp, 0);
+ verify_tree (expr, &before_sp, &after_sp, NULL_TREE);
warn_for_collisions (after_sp);
obstack_free (&tlist_obstack, tlist_firstobj);
}
--- /dev/null
+// PR c++/98126
+// { dg-do compile }
+// { dg-options "-Wsequence-point" }
+// Make sure we don't hang when verify_tree processes a large expression.
+
+struct T { bool operator==(const T &ot) const; };
+
+#define CMP(M, N, L) t[100 * M + 10 * N + L] == ot.t[100 * M + 10 * N + L] &&
+
+#define CMP1(M, N) \
+ CMP(M, N, 0) \
+ CMP(M, N, 1) \
+ CMP(M, N, 2) \
+ CMP(M, N, 3) \
+ CMP(M, N, 4) \
+ CMP(M, N, 5) \
+ CMP(M, N, 6) \
+ CMP(M, N, 7) \
+ CMP(M, N, 8) \
+ CMP(M, N, 9)
+
+#define CMP2(M) \
+ CMP1(M, 0) \
+ CMP1(M, 1) \
+ CMP1(M, 2) \
+ CMP1(M, 3) \
+ CMP1(M, 4) \
+ CMP1(M, 5) \
+ CMP1(M, 6) \
+ CMP1(M, 7) \
+ CMP1(M, 8) \
+ CMP1(M, 9)
+
+#define GENERATE_CMPS \
+ CMP2(0) \
+ CMP2(1) \
+ CMP2(2) \
+ CMP2(3) \
+ CMP2(4) \
+ CMP2(5) \
+ CMP2(6) \
+ CMP2(7) \
+ CMP2(8) \
+ CMP2(9)
+
+struct C {
+ bool operator==(const C &ot) const {
+ return
+ GENERATE_CMPS
+ true;
+ }
+ T t[999];
+};