HLSL: fix crash on empty struct return from entry point
authorsteve-lunarg <steve_gh@khasekhemwy.net>
Fri, 24 Mar 2017 14:56:37 +0000 (08:56 -0600)
committersteve-lunarg <steve_gh@khasekhemwy.net>
Fri, 24 Mar 2017 14:56:37 +0000 (08:56 -0600)
Test/baseResults/hlsl.emptystructreturn.frag.out [new file with mode: 0644]
Test/baseResults/hlsl.emptystructreturn.vert.out [new file with mode: 0644]
Test/hlsl.emptystructreturn.frag [new file with mode: 0644]
Test/hlsl.emptystructreturn.vert [new file with mode: 0644]
gtests/Hlsl.FromFile.cpp
hlsl/hlslParseHelper.cpp

diff --git a/Test/baseResults/hlsl.emptystructreturn.frag.out b/Test/baseResults/hlsl.emptystructreturn.frag.out
new file mode 100644 (file)
index 0000000..e0da985
--- /dev/null
@@ -0,0 +1,101 @@
+hlsl.emptystructreturn.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:10  Function Definition: @main(struct-ps_in1; ( temp structure{})
+0:10    Function Parameters: 
+0:10      'i' ( in structure{})
+0:?     Sequence
+0:12      Branch: Return with expression
+0:12        'o' ( temp structure{})
+0:10  Function Definition: main( ( temp void)
+0:10    Function Parameters: 
+0:?     Sequence
+0:10      move second child to first child ( temp structure{})
+0:?         'i' ( temp structure{})
+0:?         'i' (layout( location=0) in structure{})
+0:10      Sequence
+0:10        move second child to first child ( temp structure{})
+0:?           '@entryPointOutput' ( out structure{})
+0:10          Function Call: @main(struct-ps_in1; ( temp structure{})
+0:?             'i' ( temp structure{})
+0:?   Linker Objects
+0:?     'i' (layout( location=0) in structure{})
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:10  Function Definition: @main(struct-ps_in1; ( temp structure{})
+0:10    Function Parameters: 
+0:10      'i' ( in structure{})
+0:?     Sequence
+0:12      Branch: Return with expression
+0:12        'o' ( temp structure{})
+0:10  Function Definition: main( ( temp void)
+0:10    Function Parameters: 
+0:?     Sequence
+0:10      move second child to first child ( temp structure{})
+0:?         'i' ( temp structure{})
+0:?         'i' (layout( location=0) in structure{})
+0:10      Sequence
+0:10        move second child to first child ( temp structure{})
+0:?           '@entryPointOutput' ( out structure{})
+0:10          Function Call: @main(struct-ps_in1; ( temp structure{})
+0:?             'i' ( temp structure{})
+0:?   Linker Objects
+0:?     'i' (layout( location=0) in structure{})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 27
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 20 23
+                              ExecutionMode 4 OriginUpperLeft
+                              Name 4  "main"
+                              Name 6  "ps_in"
+                              Name 8  "ps_out"
+                              Name 11  "@main(struct-ps_in1;"
+                              Name 10  "i"
+                              Name 14  "o"
+                              Name 18  "i"
+                              Name 20  "i"
+                              Name 23  "@entryPointOutput"
+                              Name 24  "param"
+                              Decorate 20(i) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+        6(ps_in):             TypeStruct
+               7:             TypePointer Function 6(ps_in)
+       8(ps_out):             TypeStruct
+               9:             TypeFunction 8(ps_out) 7(ptr)
+              13:             TypePointer Function 8(ps_out)
+              19:             TypePointer Input 6(ps_in)
+           20(i):     19(ptr) Variable Input
+              22:             TypePointer Output 8(ps_out)
+23(@entryPointOutput):     22(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+           18(i):      7(ptr) Variable Function
+       24(param):      7(ptr) Variable Function
+              21:    6(ps_in) Load 20(i)
+                              Store 18(i) 21
+              25:    6(ps_in) Load 18(i)
+                              Store 24(param) 25
+              26:   8(ps_out) FunctionCall 11(@main(struct-ps_in1;) 24(param)
+                              Store 23(@entryPointOutput) 26
+                              Return
+                              FunctionEnd
+11(@main(struct-ps_in1;):   8(ps_out) Function None 9
+           10(i):      7(ptr) FunctionParameter
+              12:             Label
+           14(o):     13(ptr) Variable Function
+              15:   8(ps_out) Load 14(o)
+                              ReturnValue 15
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.emptystructreturn.vert.out b/Test/baseResults/hlsl.emptystructreturn.vert.out
new file mode 100644 (file)
index 0000000..ff89352
--- /dev/null
@@ -0,0 +1,98 @@
+hlsl.emptystructreturn.vert
+Shader version: 450
+0:? Sequence
+0:10  Function Definition: @main(struct-vs_in1; ( temp structure{})
+0:10    Function Parameters: 
+0:10      'i' ( in structure{})
+0:?     Sequence
+0:12      Branch: Return with expression
+0:12        'o' ( temp structure{})
+0:10  Function Definition: main( ( temp void)
+0:10    Function Parameters: 
+0:?     Sequence
+0:10      Sequence
+0:10        move second child to first child ( temp structure{})
+0:?           'i' ( temp structure{})
+0:?           'i' ( in structure{})
+0:10      move second child to first child ( temp structure{})
+0:?         '@entryPointOutput' (layout( location=0) out structure{})
+0:10        Function Call: @main(struct-vs_in1; ( temp structure{})
+0:?           'i' ( temp structure{})
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout( location=0) out structure{})
+
+
+Linked vertex stage:
+
+
+Shader version: 450
+0:? Sequence
+0:10  Function Definition: @main(struct-vs_in1; ( temp structure{})
+0:10    Function Parameters: 
+0:10      'i' ( in structure{})
+0:?     Sequence
+0:12      Branch: Return with expression
+0:12        'o' ( temp structure{})
+0:10  Function Definition: main( ( temp void)
+0:10    Function Parameters: 
+0:?     Sequence
+0:10      Sequence
+0:10        move second child to first child ( temp structure{})
+0:?           'i' ( temp structure{})
+0:?           'i' ( in structure{})
+0:10      move second child to first child ( temp structure{})
+0:?         '@entryPointOutput' (layout( location=0) out structure{})
+0:10        Function Call: @main(struct-vs_in1; ( temp structure{})
+0:?           'i' ( temp structure{})
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout( location=0) out structure{})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 27
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 20 23
+                              Name 4  "main"
+                              Name 6  "vs_in"
+                              Name 8  "vs_out"
+                              Name 11  "@main(struct-vs_in1;"
+                              Name 10  "i"
+                              Name 14  "o"
+                              Name 18  "i"
+                              Name 20  "i"
+                              Name 23  "@entryPointOutput"
+                              Name 24  "param"
+                              Decorate 23(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+        6(vs_in):             TypeStruct
+               7:             TypePointer Function 6(vs_in)
+       8(vs_out):             TypeStruct
+               9:             TypeFunction 8(vs_out) 7(ptr)
+              13:             TypePointer Function 8(vs_out)
+              19:             TypePointer Input 6(vs_in)
+           20(i):     19(ptr) Variable Input
+              22:             TypePointer Output 8(vs_out)
+23(@entryPointOutput):     22(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+           18(i):      7(ptr) Variable Function
+       24(param):      7(ptr) Variable Function
+              21:    6(vs_in) Load 20(i)
+                              Store 18(i) 21
+              25:    6(vs_in) Load 18(i)
+                              Store 24(param) 25
+              26:   8(vs_out) FunctionCall 11(@main(struct-vs_in1;) 24(param)
+                              Store 23(@entryPointOutput) 26
+                              Return
+                              FunctionEnd
+11(@main(struct-vs_in1;):   8(vs_out) Function None 9
+           10(i):      7(ptr) FunctionParameter
+              12:             Label
+           14(o):     13(ptr) Variable Function
+              15:   8(vs_out) Load 14(o)
+                              ReturnValue 15
+                              FunctionEnd
diff --git a/Test/hlsl.emptystructreturn.frag b/Test/hlsl.emptystructreturn.frag
new file mode 100644 (file)
index 0000000..f6a772a
--- /dev/null
@@ -0,0 +1,13 @@
+struct ps_in\r
+{\r
+};\r
+\r
+struct ps_out \r
+{\r
+};\r
+\r
+ps_out main (ps_in i)\r
+{ \r
+    ps_out o;\r
+    return o;\r
+}\r
diff --git a/Test/hlsl.emptystructreturn.vert b/Test/hlsl.emptystructreturn.vert
new file mode 100644 (file)
index 0000000..8ac6578
--- /dev/null
@@ -0,0 +1,13 @@
+struct vs_in
+{
+};
+
+struct vs_out 
+{
+};
+
+vs_out main (vs_in i)
+{ 
+    vs_out o;
+    return o;
+}
index 46e30be..0b68aea 100644 (file)
@@ -100,6 +100,8 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.depthLess.frag", "PixelShaderFunction"},
         {"hlsl.discard.frag", "PixelShaderFunction"},
         {"hlsl.doLoop.frag", "PixelShaderFunction"},
+        {"hlsl.emptystructreturn.frag", "main"},
+        {"hlsl.emptystructreturn.vert", "main"},
         {"hlsl.entry-in.frag", "PixelShaderFunction"},
         {"hlsl.entry-out.frag", "PixelShaderFunction"},
         {"hlsl.float1.frag", "PixelShaderFunction"},
index ae1d69d..48b94b6 100755 (executable)
@@ -2100,6 +2100,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
             int memberL = 0;
             int memberR = 0;
 
+            // Handle empty structure assignment
+            if (int(membersL.size()) == 0 && int(membersR.size()) == 0)
+                assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, left, right, loc), loc);
+
             for (int member = 0; member < int(membersL.size()); ++member) {
                 const TType& typeL = *membersL[member].type;
                 const TType& typeR = *membersR[member].type;