From ee1ced9dc5c4e591d8cf049b34ae25175f53285f Mon Sep 17 00:00:00 2001 From: "Juan A. Suarez Romero" Date: Tue, 18 Jun 2024 17:42:29 +0200 Subject: [PATCH] glsl: fix downcasting addresses to wrong object types This fixes several downcasting of address to object types when the original object types were either different or invalid. This has been detected throught Undefined Behaviour Sanitizer (UBSan). An example of such issue were: `downcast of address 0x55559c0cbcc0 which does not point to an object of type 'ir_variable' 0x55559c0cbcc0: note: object is of type 'ir_constant' Reviewed-by: Alyssa Rosenzweig Signed-off-by: Juan A. Suarez Romero Part-of: --- src/compiler/glsl/ast_function.cpp | 7 +++++-- src/compiler/glsl/glsl_to_nir.cpp | 8 ++++---- src/compiler/glsl/lower_jumps.cpp | 7 ++++--- src/compiler/glsl/opt_dead_code_local.cpp | 8 +++++--- src/compiler/glsl/opt_tree_grafting.cpp | 17 ++++++++++------- 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/compiler/glsl/ast_function.cpp b/src/compiler/glsl/ast_function.cpp index 464f1ba8a15..4a336a46ef0 100644 --- a/src/compiler/glsl/ast_function.cpp +++ b/src/compiler/glsl/ast_function.cpp @@ -97,8 +97,11 @@ prototype_string(const glsl_type *return_type, const char *name, ralloc_asprintf_append(&str, "%s(", name); const char *comma = ""; - foreach_in_list(const ir_variable, param, parameters) { - ralloc_asprintf_append(&str, "%s%s", comma, glsl_get_type_name(param->type)); + foreach_in_list(const ir_instruction, param, parameters) { + ralloc_asprintf_append(&str, "%s%s", comma, + glsl_get_type_name(param->ir_type == + ir_type_variable ? ((ir_variable *)param)->type : + ((ir_rvalue *)param)->type)); comma = ", "; } diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index 3b2f8b722a9..cb185760fb4 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -1153,7 +1153,7 @@ nir_visitor::visit(ir_call *ir) /* Set the intrinsic parameters. */ if (!param->is_tail_sentinel()) { instr->src[1] = - nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); + nir_src_for_ssa(evaluate_rvalue((ir_rvalue *)param)); param = param->get_next(); } @@ -1234,7 +1234,7 @@ nir_visitor::visit(ir_call *ir) * components. */ nir_def *src_addr = - evaluate_rvalue((ir_dereference *)param); + evaluate_rvalue((ir_rvalue *)param); nir_def *srcs[4]; for (int i = 0; i < 4; i++) { @@ -1261,7 +1261,7 @@ nir_visitor::visit(ir_call *ir) /* Set the intrinsic parameters. */ if (!param->is_tail_sentinel()) { instr->src[3] = - nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); + nir_src_for_ssa(evaluate_rvalue((ir_rvalue *)param)); param = param->get_next(); } else if (op == nir_intrinsic_image_deref_load || op == nir_intrinsic_image_deref_sparse_load) { @@ -1270,7 +1270,7 @@ nir_visitor::visit(ir_call *ir) if (!param->is_tail_sentinel()) { instr->src[4] = - nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param)); + nir_src_for_ssa(evaluate_rvalue((ir_rvalue *)param)); param = param->get_next(); } else if (op == nir_intrinsic_image_deref_store) { instr->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0)); /* LOD */ diff --git a/src/compiler/glsl/lower_jumps.cpp b/src/compiler/glsl/lower_jumps.cpp index e2c7da8d1b5..aec80d7e44b 100644 --- a/src/compiler/glsl/lower_jumps.cpp +++ b/src/compiler/glsl/lower_jumps.cpp @@ -722,9 +722,10 @@ lower_continue: * any instructions that that are already wrapped in the * appropriate guard. */ - ir_instruction* ir_after; - for(ir_after = (ir_instruction*)ir->get_next(); !ir_after->is_tail_sentinel();) + exec_node *node; + for(node = ir->get_next(); !node->is_tail_sentinel();) { + ir_instruction* ir_after = (ir_instruction*)node; ir_if* ir_if = ir_after->as_if(); if(ir_if && ir_if->else_instructions.is_empty()) { ir_dereference_variable* ir_if_cond_deref = ir_if->condition->as_dereference_variable(); @@ -736,7 +737,7 @@ lower_continue: continue; } } - ir_after = (ir_instruction*)ir_after->get_next(); + node = ir_after->get_next(); /* only set this if we find any unprotected instruction */ this->progress = true; diff --git a/src/compiler/glsl/opt_dead_code_local.cpp b/src/compiler/glsl/opt_dead_code_local.cpp index 5899a5215ee..e1643d005d8 100644 --- a/src/compiler/glsl/opt_dead_code_local.cpp +++ b/src/compiler/glsl/opt_dead_code_local.cpp @@ -303,7 +303,8 @@ dead_code_local_basic_block(ir_instruction *first, ir_instruction *last, void *data) { - ir_instruction *ir, *ir_next; + ir_instruction *ir; + exec_node *node, *node_next; /* List of avaialble_copy */ exec_list assignments; bool *out_progress = (bool *)data; @@ -313,8 +314,9 @@ dead_code_local_basic_block(ir_instruction *first, linear_ctx *lin_ctx = linear_context(ctx); /* Safe looping, since process_assignment */ - for (ir = first, ir_next = (ir_instruction *)first->next;; - ir = ir_next, ir_next = (ir_instruction *)ir->next) { + for (node = first, node_next = first->next;; + node = node_next, node_next = node->next) { + ir = (ir_instruction *) node; ir_assignment *ir_assign = ir->as_assignment(); if (debug) { diff --git a/src/compiler/glsl/opt_tree_grafting.cpp b/src/compiler/glsl/opt_tree_grafting.cpp index e5b96176dba..6ed8da99d5e 100644 --- a/src/compiler/glsl/opt_tree_grafting.cpp +++ b/src/compiler/glsl/opt_tree_grafting.cpp @@ -323,9 +323,10 @@ try_tree_grafting(ir_assignment *start, fprintf(stderr, "\n"); } - for (ir_instruction *ir = (ir_instruction *)start->next; - ir != bb_last->next; - ir = (ir_instruction *)ir->next) { + for (exec_node *node = start->next; + node != bb_last->next; + node = node->next) { + ir_instruction *ir = (ir_instruction *) node; if (debug) { fprintf(stderr, "- "); @@ -347,11 +348,13 @@ tree_grafting_basic_block(ir_instruction *bb_first, void *data) { struct tree_grafting_info *info = (struct tree_grafting_info *)data; - ir_instruction *ir, *next; + ir_instruction *ir; + exec_node *node, *node_next; - for (ir = bb_first, next = (ir_instruction *)ir->next; - ir != bb_last->next; - ir = next, next = (ir_instruction *)ir->next) { + for (node = bb_first, node_next = bb_first->next; + node != bb_last->next; + node = node_next, node_next = node->next) { + ir = (ir_instruction *) node; ir_assignment *assign = ir->as_assignment(); if (!assign)