[Mesa-dev] [PATCH 2/5] compiler/list: add and use for_range_list_safe
Nicolai Hähnle
nhaehnle at gmail.com
Sat May 7 22:05:05 UTC 2016
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
This macro avoids undefined behaviour that crashes gcc's ubsan.
---
src/compiler/glsl/list.h | 13 +++++++++++++
src/compiler/glsl/opt_dead_code_local.cpp | 7 +------
src/compiler/glsl/opt_tree_grafting.cpp | 5 +----
3 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/src/compiler/glsl/list.h b/src/compiler/glsl/list.h
index 8da9514..12389aa 100644
--- a/src/compiler/glsl/list.h
+++ b/src/compiler/glsl/list.h
@@ -716,4 +716,17 @@ inline void exec_node::insert_before(exec_list *before)
(((__node) = exec_node_data(__type, __cur, __field)) || true); \
__cur = __prev, __prev = __prev->prev)
+/**
+ * Iterate over a range [begin, end) of nodes.
+ */
+#define for_range_list_safe(__type, __node, __begin, __end) \
+ for (__type *(__node), **__flag = &(__node); __flag; __flag = NULL) \
+ for (struct exec_node *__cur = (__begin), \
+ *__next = __cur->next, \
+ *__end_stored = (__end); \
+ __cur != __end_stored && \
+ (((__node) = (__type *) __cur) || true); \
+ __cur = __next, __next = __next->next)
+
+
#endif /* LIST_CONTAINER_H */
diff --git a/src/compiler/glsl/opt_dead_code_local.cpp b/src/compiler/glsl/opt_dead_code_local.cpp
index d38fd2b..5dd3bfd 100644
--- a/src/compiler/glsl/opt_dead_code_local.cpp
+++ b/src/compiler/glsl/opt_dead_code_local.cpp
@@ -291,7 +291,6 @@ dead_code_local_basic_block(ir_instruction *first,
ir_instruction *last,
void *data)
{
- ir_instruction *ir, *ir_next;
/* List of avaialble_copy */
exec_list assignments;
bool *out_progress = (bool *)data;
@@ -299,8 +298,7 @@ dead_code_local_basic_block(ir_instruction *first,
void *ctx = ralloc_context(NULL);
/* Safe looping, since process_assignment */
- for (ir = first, ir_next = (ir_instruction *)first->next;;
- ir = ir_next, ir_next = (ir_instruction *)ir->next) {
+ for_range_list_safe(ir_instruction, ir, first, last->next) {
ir_assignment *ir_assign = ir->as_assignment();
if (debug) {
@@ -314,9 +312,6 @@ dead_code_local_basic_block(ir_instruction *first,
kill_for_derefs_visitor kill(&assignments);
ir->accept(&kill);
}
-
- if (ir == last)
- break;
}
*out_progress = progress;
ralloc_free(ctx);
diff --git a/src/compiler/glsl/opt_tree_grafting.cpp b/src/compiler/glsl/opt_tree_grafting.cpp
index a40e5f7..47fca7d 100644
--- a/src/compiler/glsl/opt_tree_grafting.cpp
+++ b/src/compiler/glsl/opt_tree_grafting.cpp
@@ -347,11 +347,8 @@ tree_grafting_basic_block(ir_instruction *bb_first,
void *data)
{
struct tree_grafting_info *info = (struct tree_grafting_info *)data;
- ir_instruction *ir, *next;
- for (ir = bb_first, next = (ir_instruction *)ir->next;
- ir != bb_last->next;
- ir = next, next = (ir_instruction *)ir->next) {
+ for_range_list_safe(ir_instruction, ir, bb_first, bb_last->next) {
ir_assignment *assign = ir->as_assignment();
if (!assign)
--
2.7.4
More information about the mesa-dev
mailing list