HLSL: fix crash on empty sequence node passed to intrinsic expansions
authorsteve-lunarg <steve_gh@khasekhemwy.net>
Fri, 31 Mar 2017 18:47:34 +0000 (12:47 -0600)
committersteve-lunarg <steve_gh@khasekhemwy.net>
Fri, 31 Mar 2017 18:47:34 +0000 (12:47 -0600)
Test/baseResults/hlsl.clip.frag.out [new file with mode: 0644]
Test/hlsl.clip.frag [new file with mode: 0644]
gtests/Hlsl.FromFile.cpp
hlsl/hlslParseHelper.cpp

diff --git a/Test/baseResults/hlsl.clip.frag.out b/Test/baseResults/hlsl.clip.frag.out
new file mode 100644 (file)
index 0000000..049bd8a
--- /dev/null
@@ -0,0 +1,122 @@
+hlsl.clip.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:3  Function Definition: GetEntitySelectClip( ( temp float)
+0:3    Function Parameters: 
+0:?     Sequence
+0:4      Branch: Return with expression
+0:4        Constant:
+0:4          1.000000
+0:8  Function Definition: @main( ( temp 4-component vector of float)
+0:8    Function Parameters: 
+0:?     Sequence
+0:9      Test condition and select ( temp void)
+0:9        Condition
+0:9        Compare Less Than ( temp bool)
+0:9          Function Call: GetEntitySelectClip( ( temp float)
+0:9          Constant:
+0:9            0.000000
+0:9        true case
+0:9        Branch: Kill
+0:11      Branch: Return with expression
+0:11        Constant:
+0:11          0.000000
+0:11          0.000000
+0:11          0.000000
+0:11          0.000000
+0:8  Function Definition: main( ( temp void)
+0:8    Function Parameters: 
+0:?     Sequence
+0:8      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:8        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:3  Function Definition: GetEntitySelectClip( ( temp float)
+0:3    Function Parameters: 
+0:?     Sequence
+0:4      Branch: Return with expression
+0:4        Constant:
+0:4          1.000000
+0:8  Function Definition: @main( ( temp 4-component vector of float)
+0:8    Function Parameters: 
+0:?     Sequence
+0:9      Test condition and select ( temp void)
+0:9        Condition
+0:9        Compare Less Than ( temp bool)
+0:9          Function Call: GetEntitySelectClip( ( temp float)
+0:9          Constant:
+0:9            0.000000
+0:9        true case
+0:9        Branch: Kill
+0:11      Branch: Return with expression
+0:11        Constant:
+0:11          0.000000
+0:11          0.000000
+0:11          0.000000
+0:11          0.000000
+0:8  Function Definition: main( ( temp void)
+0:8    Function Parameters: 
+0:?     Sequence
+0:8      move second child to first child ( temp 4-component vector of float)
+0:?         '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+0:8        Function Call: @main( ( temp 4-component vector of float)
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout( location=0) out 4-component vector of float)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 30
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 28
+                              ExecutionMode 4 OriginUpperLeft
+                              Name 4  "main"
+                              Name 8  "GetEntitySelectClip("
+                              Name 12  "@main("
+                              Name 28  "@entryPointOutput"
+                              Decorate 28(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeFunction 6(float)
+              10:             TypeVector 6(float) 4
+              11:             TypeFunction 10(fvec4)
+              14:    6(float) Constant 1065353216
+              18:    6(float) Constant 0
+              19:             TypeBool
+              24:   10(fvec4) ConstantComposite 18 18 18 18
+              27:             TypePointer Output 10(fvec4)
+28(@entryPointOutput):     27(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              29:   10(fvec4) FunctionCall 12(@main()
+                              Store 28(@entryPointOutput) 29
+                              Return
+                              FunctionEnd
+8(GetEntitySelectClip():    6(float) Function None 7
+               9:             Label
+                              ReturnValue 14
+                              FunctionEnd
+      12(@main():   10(fvec4) Function None 11
+              13:             Label
+              17:    6(float) FunctionCall 8(GetEntitySelectClip()
+              20:    19(bool) FOrdLessThan 17 18
+                              SelectionMerge 22 None
+                              BranchConditional 20 21 22
+              21:               Label
+                                Kill
+              22:             Label
+                              ReturnValue 24
+                              FunctionEnd
diff --git a/Test/hlsl.clip.frag b/Test/hlsl.clip.frag
new file mode 100644 (file)
index 0000000..a44c9e9
--- /dev/null
@@ -0,0 +1,12 @@
+
+float GetEntitySelectClip()
+{
+    return 1.0f;
+}
+
+float4 main() : SV_TARGET
+{
+    clip(GetEntitySelectClip());
+
+    return 0;
+}
index abc9e8d..fe47182 100644 (file)
@@ -93,6 +93,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.calculatelod.dx10.frag", "main"},
         {"hlsl.calculatelodunclamped.dx10.frag", "main"},
         {"hlsl.cast.frag", "PixelShaderFunction"},
+        {"hlsl.clip.frag", "main"},
         {"hlsl.comparison.vec.frag", "main"},
         {"hlsl.conditional.frag", "PixelShaderFunction"},
         {"hlsl.constructexpr.frag", "main"},
index 8b3a993..60ce115 100755 (executable)
@@ -2272,6 +2272,9 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
     if (argAggregate == nullptr)
         return;
 
+    if (argAggregate->getSequence().empty())
+        return;
+
     // Buffer is the object upon which method is called, so always arg 0
     TIntermTyped* bufferObj = argAggregate->getSequence()[0]->getAsTyped();
 
@@ -3747,7 +3750,9 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
         // the symbol table for an arbitrary type.  This is a temporary hack until that ability exists.
         // It will have false positives, since it doesn't check arg counts or types.
         if (arguments && arguments->getAsAggregate()) {
-            if (isStructBufferType(arguments->getAsAggregate()->getSequence()[0]->getAsTyped()->getType())) {
+            const TIntermSequence& sequence = arguments->getAsAggregate()->getSequence();
+
+            if (!sequence.empty() && isStructBufferType(sequence[0]->getAsTyped()->getType())) {
                 static const int methodPrefixSize = sizeof(BUILTIN_PREFIX)-1;
 
                 if (function->getName().length() > methodPrefixSize &&