From 1e275c8486325aaab34734ad9a650c0121c5efdb Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Wed, 14 Dec 2016 17:02:32 -0700 Subject: [PATCH] HLSL: More robust handling of bad shader input, catching a few more things. --- SPIRV/SpvBuilder.cpp | 1 + .../hlsl.array.implicit-size.frag.out | 132 +++++++++--------- Test/hlsl.array.implicit-size.frag | 1 + glslang/Include/revision.h | 4 +- hlsl/hlslParseHelper.cpp | 16 ++- hlsl/hlslParseHelper.h | 2 +- 6 files changed, 82 insertions(+), 74 deletions(-) diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 04b0f04f5..b0b74b243 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -2144,6 +2144,7 @@ void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizz std::vector oldSwizzle = accessChain.swizzle; accessChain.swizzle.resize(0); for (unsigned int i = 0; i < swizzle.size(); ++i) { + assert(swizzle[i] < oldSwizzle.size()); accessChain.swizzle.push_back(oldSwizzle[swizzle[i]]); } } else diff --git a/Test/baseResults/hlsl.array.implicit-size.frag.out b/Test/baseResults/hlsl.array.implicit-size.frag.out index 5674cb479..5f2036226 100644 --- a/Test/baseResults/hlsl.array.implicit-size.frag.out +++ b/Test/baseResults/hlsl.array.implicit-size.frag.out @@ -41,38 +41,38 @@ gl_FragCoord origin is upper left 0:28 1.000000 0:28 2.000000 0:28 3.000000 -0:30 move second child to first child (temp 4-component vector of float) -0:30 color: direct index for structure (temp 4-component vector of float) -0:30 'ps_output' (out structure{temp 4-component vector of float color}) -0:30 Constant: -0:30 0 (const int) -0:30 Construct vec4 (temp 4-component vector of float) -0:30 add (temp float) -0:30 add (temp float) -0:30 add (temp float) -0:30 add (temp float) -0:30 direct index (temp float) -0:30 'g_array' (global 5-element array of float) -0:30 Constant: -0:30 0 (const int) -0:30 direct index (temp float) -0:30 'g_array' (global 5-element array of float) -0:30 Constant: -0:30 4 (const int) -0:30 direct index (temp float) -0:30 'l_array' (temp 3-element array of float) -0:30 Constant: -0:30 1 (const int) -0:30 f: direct index for structure (temp float) -0:30 direct index (temp structure{temp int i, temp float f}) -0:30 'g_mystruct' (global 2-element array of structure{temp int i, temp float f}) -0:30 Constant: -0:30 0 (const int) -0:30 Constant: -0:30 1 (const int) -0:30 indirect index (temp float) -0:30 'g_array' (global 5-element array of float) -0:30 'idx' (temp void) +0:31 move second child to first child (temp 4-component vector of float) +0:31 color: direct index for structure (temp 4-component vector of float) +0:31 'ps_output' (out structure{temp 4-component vector of float color}) +0:31 Constant: +0:31 0 (const int) +0:31 Construct vec4 (temp 4-component vector of float) +0:31 add (temp float) +0:31 add (temp float) +0:31 add (temp float) +0:31 add (temp float) +0:31 direct index (temp float) +0:31 'g_array' (global 5-element array of float) +0:31 Constant: +0:31 0 (const int) +0:31 direct index (temp float) +0:31 'g_array' (global 5-element array of float) +0:31 Constant: +0:31 4 (const int) +0:31 direct index (temp float) +0:31 'l_array' (temp 3-element array of float) +0:31 Constant: +0:31 1 (const int) +0:31 f: direct index for structure (temp float) +0:31 direct index (temp structure{temp int i, temp float f}) +0:31 'g_mystruct' (global 2-element array of structure{temp int i, temp float f}) +0:31 Constant: +0:31 0 (const int) +0:31 Constant: +0:31 1 (const int) +0:31 indirect index (temp float) +0:31 'g_array' (global 5-element array of float) +0:31 'idx' (temp int) 0:? Linker Objects 0:? 'g_array' (global 5-element array of float) 0:? 'g_array_unused' (global 7-element array of float) @@ -125,38 +125,38 @@ gl_FragCoord origin is upper left 0:28 1.000000 0:28 2.000000 0:28 3.000000 -0:30 move second child to first child (temp 4-component vector of float) -0:30 color: direct index for structure (temp 4-component vector of float) -0:30 'ps_output' (out structure{temp 4-component vector of float color}) -0:30 Constant: -0:30 0 (const int) -0:30 Construct vec4 (temp 4-component vector of float) -0:30 add (temp float) -0:30 add (temp float) -0:30 add (temp float) -0:30 add (temp float) -0:30 direct index (temp float) -0:30 'g_array' (global 5-element array of float) -0:30 Constant: -0:30 0 (const int) -0:30 direct index (temp float) -0:30 'g_array' (global 5-element array of float) -0:30 Constant: -0:30 4 (const int) -0:30 direct index (temp float) -0:30 'l_array' (temp 3-element array of float) -0:30 Constant: -0:30 1 (const int) -0:30 f: direct index for structure (temp float) -0:30 direct index (temp structure{temp int i, temp float f}) -0:30 'g_mystruct' (global 2-element array of structure{temp int i, temp float f}) -0:30 Constant: -0:30 0 (const int) -0:30 Constant: -0:30 1 (const int) -0:30 indirect index (temp float) -0:30 'g_array' (global 5-element array of float) -0:30 'idx' (temp void) +0:31 move second child to first child (temp 4-component vector of float) +0:31 color: direct index for structure (temp 4-component vector of float) +0:31 'ps_output' (out structure{temp 4-component vector of float color}) +0:31 Constant: +0:31 0 (const int) +0:31 Construct vec4 (temp 4-component vector of float) +0:31 add (temp float) +0:31 add (temp float) +0:31 add (temp float) +0:31 add (temp float) +0:31 direct index (temp float) +0:31 'g_array' (global 5-element array of float) +0:31 Constant: +0:31 0 (const int) +0:31 direct index (temp float) +0:31 'g_array' (global 5-element array of float) +0:31 Constant: +0:31 4 (const int) +0:31 direct index (temp float) +0:31 'l_array' (temp 3-element array of float) +0:31 Constant: +0:31 1 (const int) +0:31 f: direct index for structure (temp float) +0:31 direct index (temp structure{temp int i, temp float f}) +0:31 'g_mystruct' (global 2-element array of structure{temp int i, temp float f}) +0:31 Constant: +0:31 0 (const int) +0:31 Constant: +0:31 1 (const int) +0:31 indirect index (temp float) +0:31 'g_array' (global 5-element array of float) +0:31 'idx' (temp int) 0:? Linker Objects 0:? 'g_array' (global 5-element array of float) 0:? 'g_array_unused' (global 7-element array of float) @@ -228,7 +228,7 @@ gl_FragCoord origin is upper left 49: TypePointer Private 6(float) 52: 32(int) Constant 4 56: TypePointer Function 6(float) - 63: TypePointer Function 2 + 63: TypePointer Function 32(int) 70: TypePointer Function 7(fvec4) 4(PixelShaderFunction): 2 Function None 3 5: Label @@ -254,7 +254,7 @@ gl_FragCoord origin is upper left 60: 49(ptr) AccessChain 37(g_mystruct) 48 38 61: 6(float) Load 60 62: 6(float) FAdd 59 61 - 65: 2 Load 64(idx) + 65: 32(int) Load 64(idx) 66: 49(ptr) AccessChain 18(g_array) 65 67: 6(float) Load 66 68: 6(float) FAdd 62 67 diff --git a/Test/hlsl.array.implicit-size.frag b/Test/hlsl.array.implicit-size.frag index 78a9283da..e7a54f466 100644 --- a/Test/hlsl.array.implicit-size.frag +++ b/Test/hlsl.array.implicit-size.frag @@ -26,6 +26,7 @@ void main(out PS_OUTPUT ps_output) { // local array sized from initializers float l_array[] = { 1, 2, 3 }; + int idx; ps_output.color = g_array[0] + g_array[4] + l_array[1] + g_mystruct[0].f + g_array[idx]; } diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index 5fda0eb42..cdddaf3b1 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "Overload400-PrecQual.1689" -#define GLSLANG_DATE "12-Dec-2016" +#define GLSLANG_REVISION "Overload400-PrecQual.1694" +#define GLSLANG_DATE "14-Dec-2016" diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 3a193dca2..62dac4bfa 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -579,8 +579,10 @@ TIntermTyped* HlslParseContext::handleVariable(const TSourceLoc& loc, TSymbol* s } // Recovery, if it wasn't found or was not a variable. - if (! variable) + if (! variable) { + error(loc, "unknown variable", string->c_str(), ""); variable = new TVariable(string, TType(EbtVoid)); + } if (variable->getType().getQualifier().isFrontEndConstant()) node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc); @@ -2781,7 +2783,7 @@ TIntermTyped* HlslParseContext::handleLengthMethod(const TSourceLoc& loc, TFunct // // Add any needed implicit conversions for function-call arguments to input parameters. // -void HlslParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const +void HlslParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) { TIntermAggregate* aggregate = arguments->getAsAggregate(); const auto setArg = [&](int argNum, TIntermNode* arg) { @@ -2809,9 +2811,13 @@ void HlslParseContext::addInputArgumentConversions(const TFunction& function, TI if (*function[i].type != arg->getType()) { // In-qualified arguments just need an extra node added above the argument to // convert to the correct type. - arg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg); - arg = intermediate.addShapeConversion(EOpFunctionCall, *function[i].type, arg); - setArg(i, arg); + TIntermTyped* convArg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg); + if (convArg != nullptr) + convArg = intermediate.addShapeConversion(EOpFunctionCall, *function[i].type, convArg); + if (convArg != nullptr) + setArg(i, convArg); + else + error(arg->getLoc(), "cannot convert input argument, argument", "", "%d", i); } else { if (wasFlattened(arg)) { // Will make a two-level subtree. diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index 206df9b88..3ffe35258 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -84,7 +84,7 @@ public: void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments); void decomposeGeometryMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments); TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*); - void addInputArgumentConversions(const TFunction&, TIntermNode*&) const; + void addInputArgumentConversions(const TFunction&, TIntermNode*&); TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&); void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&); TFunction* handleConstructorCall(const TSourceLoc&, const TType&);