From e01193af325cbdde51b3219c85c58f19d5a87f1b Mon Sep 17 00:00:00 2001
From: Carl Worth <cworth@cworth.org>
Date: Wed, 23 Jun 2010 18:25:04 -0700
Subject: Close memory leak in ir_call::get_error_instruction.

By propagating a 'ctx' parameter through these calls.

This fix happens to have no impact on glsl-orangebook-ch06-bump.frag,
(since it doesn't trigger any errors).
---
 ast_function.cpp        | 32 +++++++++++++++++---------------
 hir_field_selection.cpp |  2 +-
 ir.cpp                  |  4 +---
 ir.h                    |  4 +++-
 4 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/ast_function.cpp b/ast_function.cpp
index 866cbc4ecd..9550d4d2f0 100644
--- a/ast_function.cpp
+++ b/ast_function.cpp
@@ -104,7 +104,7 @@ process_call(exec_list *instructions, ir_function *f,
        */
       _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
 		       f->name);
-      return ir_call::get_error_instruction();
+      return ir_call::get_error_instruction(ctx);
    }
 }
 
@@ -114,11 +114,12 @@ match_function_by_name(exec_list *instructions, const char *name,
 		       YYLTYPE *loc, exec_list *actual_parameters,
 		       struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    ir_function *f = state->symbols->get_function(name);
 
    if (f == NULL) {
       _mesa_glsl_error(loc, state, "function `%s' undeclared", name);
-      return ir_call::get_error_instruction();
+      return ir_call::get_error_instruction(ctx);
    }
 
    /* Once we've determined that the function being called might exist, try
@@ -238,6 +239,7 @@ process_array_constructor(exec_list *instructions,
 			  YYLTYPE *loc, exec_list *parameters,
 			  struct _mesa_glsl_parse_state *state)
 {
+   void *ctx = talloc_parent(state);
    /* Array constructors come in two forms: sized and unsized.  Sized array
     * constructors look like 'vec4[2](a, b)', where 'a' and 'b' are vec4
     * variables.  In this case the number of parameters must exactly match the
@@ -272,7 +274,7 @@ process_array_constructor(exec_list *instructions,
 		       "parameter%s",
 		       (constructor_type->length != 0) ? "at least" : "exactly",
 		       min_param, (min_param <= 1) ? "" : "s");
-      return ir_call::get_error_instruction();
+      return ir_call::get_error_instruction(ctx);
    }
 
    if (constructor_type->length == 0) {
@@ -468,14 +470,14 @@ ast_function_expression::hir(exec_list *instructions,
       if (constructor_type->is_sampler()) {
 	 _mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'",
 			  constructor_type->name);
-	 return ir_call::get_error_instruction();
+	 return ir_call::get_error_instruction(ctx);
       }
 
       if (constructor_type->is_array()) {
 	 if (state->language_version <= 110) {
 	    _mesa_glsl_error(& loc, state,
 			     "array constructors forbidden in GLSL 1.10");
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 return process_array_constructor(instructions, constructor_type,
@@ -525,7 +527,7 @@ ast_function_expression::hir(exec_list *instructions,
 	    _mesa_glsl_error(& loc, state, "too few components to construct "
 			     "`%s'",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 foreach_list (n, &this->expressions) {
@@ -555,14 +557,14 @@ ast_function_expression::hir(exec_list *instructions,
 	       _mesa_glsl_error(& loc, state, "too many parameters to `%s' "
 				"constructor",
 				constructor_type->name);
-	       return ir_call::get_error_instruction();
+	       return ir_call::get_error_instruction(ctx);
 	    }
 
 	    if (!result->type->is_numeric() && !result->type->is_boolean()) {
 	       _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
 				"non-numeric data type",
 				constructor_type->name);
-	       return ir_call::get_error_instruction();
+	       return ir_call::get_error_instruction(ctx);
 	    }
 
 	    /* Count the number of matrix and nonmatrix parameters.  This
@@ -637,7 +639,7 @@ ast_function_expression::hir(exec_list *instructions,
 	    _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
 			     "matrix in GLSL 1.10",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
@@ -651,7 +653,7 @@ ast_function_expression::hir(exec_list *instructions,
 	    _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, "
 			     "matrix must be only parameter",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
@@ -664,14 +666,14 @@ ast_function_expression::hir(exec_list *instructions,
 	    _mesa_glsl_error(& loc, state, "too few components to construct "
 			     "`%s'",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 ir_function *f = state->symbols->get_function(constructor_type->name);
 	 if (f == NULL) {
 	    _mesa_glsl_error(& loc, state, "no constructor for type `%s'",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
 
 	 const ir_function_signature *sig =
@@ -715,11 +717,11 @@ ast_function_expression::hir(exec_list *instructions,
 	     */
 	    _mesa_glsl_error(& loc, state, "no matching constructor for `%s'",
 			     constructor_type->name);
-	    return ir_call::get_error_instruction();
+	    return ir_call::get_error_instruction(ctx);
 	 }
       }
 
-      return ir_call::get_error_instruction();
+      return ir_call::get_error_instruction(ctx);
    } else {
       const ast_expression *id = subexpressions[0];
       YYLTYPE loc = id->get_location();
@@ -744,5 +746,5 @@ ast_function_expression::hir(exec_list *instructions,
 				    &actual_parameters, state);
    }
 
-   return ir_call::get_error_instruction();
+   return ir_call::get_error_instruction(ctx);
 }
diff --git a/hir_field_selection.cpp b/hir_field_selection.cpp
index 6da14925b9..e2efff60d3 100644
--- a/hir_field_selection.cpp
+++ b/hir_field_selection.cpp
@@ -77,5 +77,5 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
 		       expr->primary_expression.identifier);
    }
 
-   return result ? result : ir_call::get_error_instruction();
+   return result ? result : ir_call::get_error_instruction(ctx);
 }
diff --git a/ir.cpp b/ir.cpp
index 26cd475552..6286d874e6 100644
--- a/ir.cpp
+++ b/ir.cpp
@@ -833,10 +833,8 @@ ir_function::ir_function(const char *name)
 
 
 ir_call *
-ir_call::get_error_instruction()
+ir_call::get_error_instruction(void *ctx)
 {
-   /* NULL is wrong and leaks */
-   void *ctx = NULL;
    ir_call *call = new(ctx) ir_call;
 
    call->type = glsl_type::error_type;
diff --git a/ir.h b/ir.h
index 68e90653ed..1c95512fb1 100644
--- a/ir.h
+++ b/ir.h
@@ -645,8 +645,10 @@ public:
 
    /**
     * Get a generic ir_call object when an error occurs
+    *
+    * Any allocation will be performed with 'ctx' as talloc owner.
     */
-   static ir_call *get_error_instruction();
+   static ir_call *get_error_instruction(void *ctx);
 
    /**
     * Get an iterator for the set of acutal parameters
-- 
cgit v1.2.3