diff --git a/Test/baseResults/hlsl.emptystructreturn.frag.out b/Test/baseResults/hlsl.emptystructreturn.frag.out new file mode 100644 index 0000000000000000000000000000000000000000..e0da9852112646f5f94b6642bf43ae2768ffae12 --- /dev/null +++ b/Test/baseResults/hlsl.emptystructreturn.frag.out @@ -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 index 0000000000000000000000000000000000000000..ff8935246aaba8da8539ae981bff39cf5ed2b698 --- /dev/null +++ b/Test/baseResults/hlsl.emptystructreturn.vert.out @@ -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 index 0000000000000000000000000000000000000000..f6a772a328380479a72ee7cdf7c9c25baebc9743 --- /dev/null +++ b/Test/hlsl.emptystructreturn.frag @@ -0,0 +1,13 @@ +struct ps_in +{ +}; + +struct ps_out +{ +}; + +ps_out main (ps_in i) +{ + ps_out o; + return o; +} diff --git a/Test/hlsl.emptystructreturn.vert b/Test/hlsl.emptystructreturn.vert new file mode 100644 index 0000000000000000000000000000000000000000..8ac6578e468fb9fbba773fc9bed784e87dffd1e6 --- /dev/null +++ b/Test/hlsl.emptystructreturn.vert @@ -0,0 +1,13 @@ +struct vs_in +{ +}; + +struct vs_out +{ +}; + +vs_out main (vs_in i) +{ + vs_out o; + return o; +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 46e30bec8ae4cbfb12036e59e89254921c7e453e..0b68aeab8275f64a5729081c72920fc0b3ebc316 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -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"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index ae1d69dbf7af2a37b7d6d08fad032f943386322e..48b94b62c4f60fb891c7e77bb8987da6ce31f6ce 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -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;