glsl: make the redeclared variable NULL if it is deleted
authorIago Toral Quiroga <itoral@igalia.com>
Wed, 13 Sep 2017 07:08:01 +0000 (09:08 +0200)
committerIago Toral Quiroga <itoral@igalia.com>
Thu, 14 Sep 2017 09:23:26 +0000 (11:23 +0200)
get_variable_being_redeclared() can delete the original variable
in a specific scenario. The code sets it to NULL after this so other
code in that same function doesn't try to access trashed memory after
the fact, however, the copy of that variable in the caller code
won't see any of this making it very easy to overlook.

Make the function a bit safer by taking a pointer to the original
variable so we can also make NULL the caller's pointer to the variable
if this function deletes it.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/compiler/glsl/ast_to_hir.cpp

index 6dd0f1dfaad7f050cd9401a71625c74cc18beb91..5600e14c31ab77c5791f955919a05e6fe791f704 100644 (file)
@@ -4166,11 +4166,13 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
  * otherwise.
  */
 static ir_variable *
-get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
+get_variable_being_redeclared(ir_variable **var_ptr, YYLTYPE loc,
                               struct _mesa_glsl_parse_state *state,
                               bool allow_all_redeclarations,
                               bool *is_redeclaration)
 {
+   ir_variable *var = *var_ptr;
+
    /* Check if this declaration is actually a re-declaration, either to
     * resize an array or add qualifiers to an existing variable.
     *
@@ -4211,6 +4213,7 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
       earlier->type = var->type;
       delete var;
       var = NULL;
+      *var_ptr = NULL;
    } else if ((state->ARB_fragment_coord_conventions_enable ||
               state->is_version(150, 0))
               && strcmp(var->name, "gl_FragCoord") == 0
@@ -5457,7 +5460,7 @@ ast_declarator_list::hir(exec_list *instructions,
 
       bool is_redeclaration;
       ir_variable *declared_var =
-         get_variable_being_redeclared(var, decl->get_location(), state,
+         get_variable_being_redeclared(&var, decl->get_location(), state,
                                        false /* allow_all_redeclarations */,
                                        &is_redeclaration);
       if (is_redeclaration) {
@@ -8215,7 +8218,7 @@ ast_interface_block::hir(exec_list *instructions,
          if (redeclaring_per_vertex) {
             bool is_redeclaration;
             ir_variable *declared_var =
-               get_variable_being_redeclared(var, loc, state,
+               get_variable_being_redeclared(&var, loc, state,
                                              true /* allow_all_redeclarations */,
                                              &is_redeclaration);
             if (!var_is_gl_id || !is_redeclaration) {