[Mesa-dev] [PATCH 5/9] glsl: Fix memcpy size in ir_constant
Ian Romanick
idr at freedesktop.org
Tue Feb 18 18:35:41 PST 2014
On 02/09/2014 01:50 AM, Juha-Pekka Heikkilä wrote:
> The place which cause Klocwork to highlight this is at
> src/mesa/main/ff_fragment_shader.cpp around line 897 where it says:
>
> ...
> float const_data[4] = {
> float(1 << rgb_shift),
> float(1 << rgb_shift),
> float(1 << rgb_shift),
> float(1 << alpha_shift)
> };
> shift = new(p->mem_ctx) ir_constant(glsl_type::vec4_type,
> (ir_constant_data *)const_data);
> ...
>
> I don't know if this is the only place for such usage but it looks
> reasonable to me.
>
> If I fix this place instead of what my patch does Klocwork would tell
> where is next similar usage for this ir_constant constructor, that is
> if such exist.
The ir_constant constructors are used in a lot of places. I'd rather
not take the extra overhead to work around callers lying about the
parameter type. If we have to keep fixing these one at a time, I'm okay
with that. The error case is (most likely) that we read some garbage
data from the stack. We should fix those, but it's not a cataclysmic
error.
Doing a quick check...
egrep -r 'new[^ ]* ir_constant[(][^,)]*,[^)]*[)]' src/
shows
src/mesa/drivers/dri/i965/brw_fs_fp.cpp: ir->coordinate = new(mem_ctx) ir_constant(coordinate_type, &junk_data);
src/glsl/builtin_functions.cpp: return new(mem_ctx) ir_constant(f, vector_elements);
src/glsl/builtin_functions.cpp: return new(mem_ctx) ir_constant(i, vector_elements);
src/glsl/builtin_functions.cpp: return new(mem_ctx) ir_constant(u, vector_elements);
src/glsl/builtin_functions.cpp: return new(mem_ctx) ir_constant(type, &data);
src/glsl/ir_clone.cpp: return new(mem_ctx) ir_constant(this->type, &this->value);
src/glsl/opt_constant_propagation.cpp: *rvalue = new(ralloc_parent(deref)) ir_constant(type, &data);
src/glsl/ir_constant_expression.cpp: return new(ctx) ir_constant(this->type, &data);
src/glsl/ir_constant_expression.cpp: return new(ctx) ir_constant(this->type, &data);
src/glsl/ir_constant_expression.cpp: return new(ctx) ir_constant(column_type, &data);
src/glsl/ir_constant_expression.cpp: return new(ctx) ir_constant(array, component);
src/glsl/opt_algebraic.cpp: return new(mem_ctx) ir_constant(ir->type, &data);
src/glsl/ast_to_hir.cpp: var->constant_value = new(var) ir_constant(glsl_type::ivec3_type, &data);
src/glsl/ast_to_hir.cpp: new(var) ir_constant(glsl_type::ivec3_type, &data);
src/glsl/lower_instructions.cpp: ir_constant *sign_mask = new(ir) ir_constant(0x80000000u, vec_elem);
src/glsl/lower_instructions.cpp: ir_constant *exp_shift = new(ir) ir_constant(23u, vec_elem);
src/glsl/lower_instructions.cpp: ir_constant *exp_width = new(ir) ir_constant(8u, vec_elem);
src/glsl/lower_instructions.cpp: new(ir) ir_constant(0x1, vec_elem))));
src/glsl/tests/uniform_initializer_utils.cpp: val = new(mem_ctx) ir_constant(type, &data);
src/glsl/tests/uniform_initializer_utils.cpp: val = new(mem_ctx) ir_constant(array_type, &values_for_array);
src/glsl/ast_function.cpp: return new(ctx) ir_constant(constant, component);
src/glsl/ast_function.cpp: return new(ctx) ir_constant(constructor_type, &actual_parameters);
src/glsl/ast_function.cpp: return new(ctx) ir_constant(constructor_type, &actual_parameters);
src/glsl/ast_function.cpp: return new(mem_ctx) ir_constant(constructor_type, parameters);
src/glsl/ast_function.cpp: ir_rvalue *rhs = new(ctx) ir_constant(rhs_type, &data);
src/glsl/ast_function.cpp: new(ctx) ir_constant(rhs_var->type, &zero),
src/glsl/ast_function.cpp: ir_rvalue *const rhs = new(ctx) ir_constant(col_type, &ident);
src/glsl/ast_function.cpp: return new(ctx) ir_constant(constructor_type, &actual_parameters);
src/glsl/ir_reader.cpp: return new(mem_ctx) ir_constant(type, &elements);
src/glsl/ir_reader.cpp: return new(mem_ctx) ir_constant(type, &data);
src/glsl/builtin_variables.cpp: var->constant_value = new(var) ir_constant(glsl_type::ivec3_type, &data);
src/glsl/builtin_variables.cpp: new(var) ir_constant(glsl_type::ivec3_type, &data);
Of those, I think we only need to audit:
src/mesa/drivers/dri/i965/brw_fs_fp.cpp: ir->coordinate = new(mem_ctx) ir_constant(coordinate_type, &junk_data);
src/glsl/builtin_functions.cpp: return new(mem_ctx) ir_constant(type, &data);
src/glsl/opt_constant_propagation.cpp: *rvalue = new(ralloc_parent(deref)) ir_constant(type, &data);
src/glsl/ir_constant_expression.cpp: return new(ctx) ir_constant(this->type, &data);
src/glsl/ir_constant_expression.cpp: return new(ctx) ir_constant(this->type, &data);
src/glsl/ir_constant_expression.cpp: return new(ctx) ir_constant(column_type, &data);
src/glsl/ir_constant_expression.cpp: return new(ctx) ir_constant(array, component);
src/glsl/opt_algebraic.cpp: return new(mem_ctx) ir_constant(ir->type, &data);
src/glsl/ast_to_hir.cpp: var->constant_value = new(var) ir_constant(glsl_type::ivec3_type, &data);
src/glsl/ast_to_hir.cpp: new(var) ir_constant(glsl_type::ivec3_type, &data);
src/glsl/tests/uniform_initializer_utils.cpp: val = new(mem_ctx) ir_constant(type, &data);
src/glsl/tests/uniform_initializer_utils.cpp: val = new(mem_ctx) ir_constant(array_type, &values_for_array);
src/glsl/ast_function.cpp: ir_rvalue *rhs = new(ctx) ir_constant(rhs_type, &data);
src/glsl/ast_function.cpp: new(ctx) ir_constant(rhs_var->type, &zero),
src/glsl/ast_function.cpp: ir_rvalue *const rhs = new(ctx) ir_constant(col_type, &ident);
src/glsl/ir_reader.cpp: return new(mem_ctx) ir_constant(type, &elements);
src/glsl/ir_reader.cpp: return new(mem_ctx) ir_constant(type, &data);
src/glsl/builtin_variables.cpp: var->constant_value = new(var) ir_constant(glsl_type::ivec3_type, &data);
src/glsl/builtin_variables.cpp: new(var) ir_constant(glsl_type::ivec3_type, &data);
I skimmed a few of these, and the ones I looked at were fine... none of
them have an explicit cast, so the compiler would complain if they
weren't fine. :)
This search obviously isn't perfect... it misses the case we're
discussing. I'm sure there's some nice cscope-like tool for C++ that
would find all the callers of that particular constructor.
> /Juha-Pekka
>
>
> On Sat, Feb 8, 2014 at 2:30 AM, Ian Romanick <idr at freedesktop.org> wrote:
>> On 02/07/2014 04:44 AM, Juha-Pekka Heikkila wrote:
>>> ir_constant::ir_constant(const struct glsl_type,
>>> const ir_constant_data *) was copying too much memory.
>>
>> The code looks correct as-is to me. This copies one ir_constant_data
>> union to another... they're declared as the same type, and they have the
>> same size. What is the actual error? Is there some code somewhere
>> that's casting a different type to ir_constant_data* to pass into this
>> constructor?
>>
>>> Signed-off-by: Juha-Pekka Heikkila <juhapekka.heikkila at gmail.com>
>>> ---
>>> src/glsl/ir.cpp | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
>>> index 1a36bd6..abc5568 100644
>>> --- a/src/glsl/ir.cpp
>>> +++ b/src/glsl/ir.cpp
>>> @@ -622,7 +622,7 @@ ir_constant::ir_constant(const struct glsl_type *type,
>>>
>>> this->ir_type = ir_type_constant;
>>> this->type = type;
>>> - memcpy(& this->value, data, sizeof(this->value));
>>> + memcpy(& this->value, data, type->std140_size(false));
>>> }
>>>
>>> ir_constant::ir_constant(float f, unsigned vector_elements)
More information about the mesa-dev
mailing list