From 8d63a3d35a931c5f514248feae6ddbd45f051391 Mon Sep 17 00:00:00 2001 From: David Neto Date: Mon, 7 Dec 2015 16:17:06 -0500 Subject: [PATCH] Avoid read past end of operands vector for EOpFrexp When emitting SPIR-V code for frexp, avoid access beyond the end of the operands vector. When constructing the OpExtInst, construct a new arguments vector instead of modifying the existing operands vector. In the case of OpFrexp, well need that last operand later on to generate the store. Fixes https://github.com/KhronosGroup/glslang/issues/110 Change-Id: Ibc380fadf5e600ac491932e9ecef7afe2d72fd7f --- SPIRV/GlslangToSpv.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 1d77b02..0fff30e 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -2893,9 +2893,11 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: spv::Id id = 0; if (libCall >= 0) { - while (consumedOperands < (int)operands.size()) - operands.pop_back(); - id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, operands); + // Use an extended instruction from the standard library. + // Construct the call arguments, without modifying the original operands vector. + // We might need the remaining arguments, e.g. in the EOpFrexp case. + std::vector callArguments(operands.begin(), operands.begin() + consumedOperands); + id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, callArguments); } else { switch (consumedOperands) { case 0: @@ -2930,6 +2932,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: builder.createStore(builder.createCompositeExtract(id, typeId0, 1), operands[2]); break; case glslang::EOpFrexp: + assert(operands.size() == 2); builder.createStore(builder.createCompositeExtract(id, frexpIntType, 1), operands[1]); id = builder.createCompositeExtract(id, typeId0, 0); break; -- 2.7.4