From 05a62bf528af14517fae42b65531b3812f88a447 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Wed, 7 Jan 2015 06:14:06 +0000 Subject: [PATCH] Implement barrier() control-flow rules: in flow control, non-main, and post-return. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@29347 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- Test/400.tesc | 27 ++++ Test/430.comp | 5 + Test/baseResults/150.tesc.out | 198 ++++++++++++++++++++--------- Test/baseResults/400.tesc.out | 198 ++++++++++++++++++++--------- Test/baseResults/430.comp.out | 112 +++++++++------- glslang/MachineIndependent/ParseHelper.cpp | 29 ++++- glslang/MachineIndependent/ParseHelper.h | 8 +- glslang/MachineIndependent/glslang.y | 30 ++++- 8 files changed, 426 insertions(+), 181 deletions(-) diff --git a/Test/400.tesc b/Test/400.tesc index 46e408f..1f0126c 100644 --- a/Test/400.tesc +++ b/Test/400.tesc @@ -34,6 +34,31 @@ void main() gl_TessLevelOuter[3] = 3.2; gl_TessLevelInner[1] = 1.3; + + if (a > 10) + barrier(); // ERROR + else + barrier(); // ERROR + + barrier(); + + do { + barrier(); // ERROR + } while (a > 10); + + switch (a) { + default: + barrier(); // ERROR + break; + } + + { + barrier(); + } + + return; + + barrier(); // ERROR } layout(vertices = 4) in; // ERROR @@ -42,6 +67,8 @@ layout(vertices = 5) out; // ERROR void foo() { gl_out[4].gl_PointSize; // ERROR + + barrier(); // ERROR } in vec2 ina; // ERROR, not array diff --git a/Test/430.comp b/Test/430.comp index f022f8f..53b4617 100644 --- a/Test/430.comp +++ b/Test/430.comp @@ -34,6 +34,10 @@ void main() memoryBarrierImage(); groupMemoryBarrier(); value = int(values[gl_LocalInvocationIndex]); + + int a; + if (a > 10) + barrier(); } layout(location = 2) in vec3 v3; // ERROR @@ -60,4 +64,5 @@ void foo() { ro.values[2] = 4.7; // ERROR, readonly ro.values.length(); + barrier(); } diff --git a/Test/baseResults/150.tesc.out b/Test/baseResults/150.tesc.out index 1d3ce1d..87e0767 100644 --- a/Test/baseResults/150.tesc.out +++ b/Test/baseResults/150.tesc.out @@ -219,14 +219,20 @@ ERROR: 0:6: 'quads' : unrecognized layout identifier, or qualifier requires assi ERROR: 0:7: 'ccw' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) ERROR: 0:8: 'fractional_even_spacing' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) ERROR: 0:10: 'patch' : can only use on output in tessellation-control shader -ERROR: 0:39: 'vertices' : can only apply to 'out' -ERROR: 0:40: 'vertices' : cannot change previously set layout value -ERROR: 0:44: '[' : array index out of range '4' -ERROR: 0:47: 'in' : type must be an array: ina -ERROR: 0:49: '[]' : tessellation input array size must be gl_MaxPatchVertices or implicitly sized -ERROR: 0:56: 'location' : overlapping use of location 4 -ERROR: 0:60: 'location' : overlapping use of location 4 -ERROR: 11 compilation errors. No code generated. +ERROR: 0:39: '' : tessellation control barrier() cannot be placed within flow control +ERROR: 0:41: '' : tessellation control barrier() cannot be placed within flow control +ERROR: 0:46: '' : tessellation control barrier() cannot be placed within flow control +ERROR: 0:51: '' : tessellation control barrier() cannot be placed within flow control +ERROR: 0:61: '' : tessellation control barrier() cannot be placed after a return from main() +ERROR: 0:64: 'vertices' : can only apply to 'out' +ERROR: 0:65: 'vertices' : cannot change previously set layout value +ERROR: 0:69: '[' : array index out of range '4' +ERROR: 0:71: '' : tessellation control barrier() must be in main() +ERROR: 0:74: 'in' : type must be an array: ina +ERROR: 0:76: '[]' : tessellation input array size must be gl_MaxPatchVertices or implicitly sized +ERROR: 0:83: 'location' : overlapping use of location 4 +ERROR: 0:87: 'location' : overlapping use of location 4 +ERROR: 17 compilation errors. No code generated. Shader version: 400 @@ -331,34 +337,68 @@ ERROR: node is still EOpNull! 0:36 1 (const int) 0:36 Constant: 0:36 1.300000 -0:42 Function Definition: foo( (void) -0:42 Function Parameters: -0:44 Sequence -0:44 gl_PointSize: direct index for structure (out float) -0:44 direct index (block{out 4-component vector of float gl_Position, out float gl_PointSize, out implicitly-sized array of float gl_ClipDistance}) -0:44 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out implicitly-sized array of float gl_ClipDistance}) -0:44 Constant: -0:44 4 (const int) -0:44 Constant: -0:44 1 (const int) -0:64 Function Definition: foop( (void) -0:64 Function Parameters: +0:38 Test condition and select (void) +0:38 Condition +0:38 Compare Greater Than (bool) +0:38 'a' (int) +0:38 Constant: +0:38 10 (const int) +0:38 true case +0:39 Barrier (void) +0:38 false case +0:41 Barrier (void) +0:43 Barrier (void) +0:47 Loop with condition not tested first +0:47 Loop Condition +0:47 Compare Greater Than (bool) +0:47 'a' (int) +0:47 Constant: +0:47 10 (const int) +0:47 Loop Body +0:46 Sequence +0:46 Barrier (void) +0:49 switch +0:49 condition +0:49 'a' (int) +0:49 body +0:49 Sequence +0:50 default: +0:? Sequence +0:51 Barrier (void) +0:52 Branch: Break +0:56 Sequence +0:56 Barrier (void) +0:59 Branch: Return +0:61 Barrier (void) +0:67 Function Definition: foo( (void) +0:67 Function Parameters: +0:69 Sequence +0:69 gl_PointSize: direct index for structure (out float) +0:69 direct index (block{out 4-component vector of float gl_Position, out float gl_PointSize, out implicitly-sized array of float gl_ClipDistance}) +0:69 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out implicitly-sized array of float gl_ClipDistance}) +0:69 Constant: +0:69 4 (const int) +0:69 Constant: +0:69 1 (const int) +0:71 Barrier (void) +0:91 Function Definition: foop( (void) +0:91 Function Parameters: 0:? Sequence -0:68 multiply second child into first child (3-component vector of float) -0:68 'pv3' (3-component vector of float) -0:68 'pv3' (3-component vector of float) -0:69 move second child to first child (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 Function Call: fma(vf3;vf3;vf3; (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:70 move second child to first child (double) -0:70 'd' (double) -0:70 Function Call: fma(d1;d1;d1; (double) -0:70 'd' (double) -0:70 'd' (double) -0:70 'd' (double) +0:95 multiply second child into first child (3-component vector of float) +0:95 'pv3' (3-component vector of float) +0:95 'pv3' (3-component vector of float) +0:96 move second child to first child (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 Function Call: fma(vf3;vf3;vf3; (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:97 move second child to first child (double) +0:97 'd' (double) +0:97 Function Call: fma(d1;d1;d1; (double) +0:97 'd' (double) +0:97 'd' (double) +0:97 'd' (double) 0:? Linker Objects 0:? 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out implicitly-sized array of float gl_ClipDistance}) 0:? 'outa' (4-element array of int) @@ -1031,34 +1071,68 @@ vertices = 4 0:36 1 (const int) 0:36 Constant: 0:36 1.300000 -0:42 Function Definition: foo( (void) -0:42 Function Parameters: -0:44 Sequence -0:44 gl_PointSize: direct index for structure (out float) -0:44 direct index (block{out 4-component vector of float gl_Position, out float gl_PointSize, out 1-element array of float gl_ClipDistance}) -0:44 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out 1-element array of float gl_ClipDistance}) -0:44 Constant: -0:44 4 (const int) -0:44 Constant: -0:44 1 (const int) -0:64 Function Definition: foop( (void) -0:64 Function Parameters: +0:38 Test condition and select (void) +0:38 Condition +0:38 Compare Greater Than (bool) +0:38 'a' (int) +0:38 Constant: +0:38 10 (const int) +0:38 true case +0:39 Barrier (void) +0:38 false case +0:41 Barrier (void) +0:43 Barrier (void) +0:47 Loop with condition not tested first +0:47 Loop Condition +0:47 Compare Greater Than (bool) +0:47 'a' (int) +0:47 Constant: +0:47 10 (const int) +0:47 Loop Body +0:46 Sequence +0:46 Barrier (void) +0:49 switch +0:49 condition +0:49 'a' (int) +0:49 body +0:49 Sequence +0:50 default: +0:? Sequence +0:51 Barrier (void) +0:52 Branch: Break +0:56 Sequence +0:56 Barrier (void) +0:59 Branch: Return +0:61 Barrier (void) +0:67 Function Definition: foo( (void) +0:67 Function Parameters: +0:69 Sequence +0:69 gl_PointSize: direct index for structure (out float) +0:69 direct index (block{out 4-component vector of float gl_Position, out float gl_PointSize, out 1-element array of float gl_ClipDistance}) +0:69 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out 1-element array of float gl_ClipDistance}) +0:69 Constant: +0:69 4 (const int) +0:69 Constant: +0:69 1 (const int) +0:71 Barrier (void) +0:91 Function Definition: foop( (void) +0:91 Function Parameters: 0:? Sequence -0:68 multiply second child into first child (3-component vector of float) -0:68 'pv3' (3-component vector of float) -0:68 'pv3' (3-component vector of float) -0:69 move second child to first child (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 Function Call: fma(vf3;vf3;vf3; (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:70 move second child to first child (double) -0:70 'd' (double) -0:70 Function Call: fma(d1;d1;d1; (double) -0:70 'd' (double) -0:70 'd' (double) -0:70 'd' (double) +0:95 multiply second child into first child (3-component vector of float) +0:95 'pv3' (3-component vector of float) +0:95 'pv3' (3-component vector of float) +0:96 move second child to first child (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 Function Call: fma(vf3;vf3;vf3; (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:97 move second child to first child (double) +0:97 'd' (double) +0:97 Function Call: fma(d1;d1;d1; (double) +0:97 'd' (double) +0:97 'd' (double) +0:97 'd' (double) 0:8 Function Definition: main( (void) 0:8 Function Parameters: 0:15 Function Definition: main( (void) diff --git a/Test/baseResults/400.tesc.out b/Test/baseResults/400.tesc.out index bd5d4b6..af2a414 100644 --- a/Test/baseResults/400.tesc.out +++ b/Test/baseResults/400.tesc.out @@ -4,14 +4,20 @@ ERROR: 0:6: 'quads' : unrecognized layout identifier, or qualifier requires assi ERROR: 0:7: 'ccw' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) ERROR: 0:8: 'fractional_even_spacing' : unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4) ERROR: 0:10: 'patch' : can only use on output in tessellation-control shader -ERROR: 0:39: 'vertices' : can only apply to 'out' -ERROR: 0:40: 'vertices' : cannot change previously set layout value -ERROR: 0:44: '[' : array index out of range '4' -ERROR: 0:47: 'in' : type must be an array: ina -ERROR: 0:49: '[]' : tessellation input array size must be gl_MaxPatchVertices or implicitly sized -ERROR: 0:56: 'location' : overlapping use of location 4 -ERROR: 0:60: 'location' : overlapping use of location 4 -ERROR: 11 compilation errors. No code generated. +ERROR: 0:39: '' : tessellation control barrier() cannot be placed within flow control +ERROR: 0:41: '' : tessellation control barrier() cannot be placed within flow control +ERROR: 0:46: '' : tessellation control barrier() cannot be placed within flow control +ERROR: 0:51: '' : tessellation control barrier() cannot be placed within flow control +ERROR: 0:61: '' : tessellation control barrier() cannot be placed after a return from main() +ERROR: 0:64: 'vertices' : can only apply to 'out' +ERROR: 0:65: 'vertices' : cannot change previously set layout value +ERROR: 0:69: '[' : array index out of range '4' +ERROR: 0:71: '' : tessellation control barrier() must be in main() +ERROR: 0:74: 'in' : type must be an array: ina +ERROR: 0:76: '[]' : tessellation input array size must be gl_MaxPatchVertices or implicitly sized +ERROR: 0:83: 'location' : overlapping use of location 4 +ERROR: 0:87: 'location' : overlapping use of location 4 +ERROR: 17 compilation errors. No code generated. Shader version: 400 @@ -116,34 +122,68 @@ ERROR: node is still EOpNull! 0:36 1 (const int) 0:36 Constant: 0:36 1.300000 -0:42 Function Definition: foo( (void) -0:42 Function Parameters: -0:44 Sequence -0:44 gl_PointSize: direct index for structure (out float) -0:44 direct index (block{out 4-component vector of float gl_Position, out float gl_PointSize, out implicitly-sized array of float gl_ClipDistance}) -0:44 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out implicitly-sized array of float gl_ClipDistance}) -0:44 Constant: -0:44 4 (const int) -0:44 Constant: -0:44 1 (const int) -0:64 Function Definition: foop( (void) -0:64 Function Parameters: +0:38 Test condition and select (void) +0:38 Condition +0:38 Compare Greater Than (bool) +0:38 'a' (int) +0:38 Constant: +0:38 10 (const int) +0:38 true case +0:39 Barrier (void) +0:38 false case +0:41 Barrier (void) +0:43 Barrier (void) +0:47 Loop with condition not tested first +0:47 Loop Condition +0:47 Compare Greater Than (bool) +0:47 'a' (int) +0:47 Constant: +0:47 10 (const int) +0:47 Loop Body +0:46 Sequence +0:46 Barrier (void) +0:49 switch +0:49 condition +0:49 'a' (int) +0:49 body +0:49 Sequence +0:50 default: +0:? Sequence +0:51 Barrier (void) +0:52 Branch: Break +0:56 Sequence +0:56 Barrier (void) +0:59 Branch: Return +0:61 Barrier (void) +0:67 Function Definition: foo( (void) +0:67 Function Parameters: +0:69 Sequence +0:69 gl_PointSize: direct index for structure (out float) +0:69 direct index (block{out 4-component vector of float gl_Position, out float gl_PointSize, out implicitly-sized array of float gl_ClipDistance}) +0:69 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out implicitly-sized array of float gl_ClipDistance}) +0:69 Constant: +0:69 4 (const int) +0:69 Constant: +0:69 1 (const int) +0:71 Barrier (void) +0:91 Function Definition: foop( (void) +0:91 Function Parameters: 0:? Sequence -0:68 multiply second child into first child (3-component vector of float) -0:68 'pv3' (3-component vector of float) -0:68 'pv3' (3-component vector of float) -0:69 move second child to first child (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 Function Call: fma(vf3;vf3;vf3; (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:70 move second child to first child (double) -0:70 'd' (double) -0:70 Function Call: fma(d1;d1;d1; (double) -0:70 'd' (double) -0:70 'd' (double) -0:70 'd' (double) +0:95 multiply second child into first child (3-component vector of float) +0:95 'pv3' (3-component vector of float) +0:95 'pv3' (3-component vector of float) +0:96 move second child to first child (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 Function Call: fma(vf3;vf3;vf3; (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:97 move second child to first child (double) +0:97 'd' (double) +0:97 Function Call: fma(d1;d1;d1; (double) +0:97 'd' (double) +0:97 'd' (double) +0:97 'd' (double) 0:? Linker Objects 0:? 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out implicitly-sized array of float gl_ClipDistance}) 0:? 'outa' (4-element array of int) @@ -268,34 +308,68 @@ ERROR: node is still EOpNull! 0:36 1 (const int) 0:36 Constant: 0:36 1.300000 -0:42 Function Definition: foo( (void) -0:42 Function Parameters: -0:44 Sequence -0:44 gl_PointSize: direct index for structure (out float) -0:44 direct index (block{out 4-component vector of float gl_Position, out float gl_PointSize, out 1-element array of float gl_ClipDistance}) -0:44 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out 1-element array of float gl_ClipDistance}) -0:44 Constant: -0:44 4 (const int) -0:44 Constant: -0:44 1 (const int) -0:64 Function Definition: foop( (void) -0:64 Function Parameters: +0:38 Test condition and select (void) +0:38 Condition +0:38 Compare Greater Than (bool) +0:38 'a' (int) +0:38 Constant: +0:38 10 (const int) +0:38 true case +0:39 Barrier (void) +0:38 false case +0:41 Barrier (void) +0:43 Barrier (void) +0:47 Loop with condition not tested first +0:47 Loop Condition +0:47 Compare Greater Than (bool) +0:47 'a' (int) +0:47 Constant: +0:47 10 (const int) +0:47 Loop Body +0:46 Sequence +0:46 Barrier (void) +0:49 switch +0:49 condition +0:49 'a' (int) +0:49 body +0:49 Sequence +0:50 default: +0:? Sequence +0:51 Barrier (void) +0:52 Branch: Break +0:56 Sequence +0:56 Barrier (void) +0:59 Branch: Return +0:61 Barrier (void) +0:67 Function Definition: foo( (void) +0:67 Function Parameters: +0:69 Sequence +0:69 gl_PointSize: direct index for structure (out float) +0:69 direct index (block{out 4-component vector of float gl_Position, out float gl_PointSize, out 1-element array of float gl_ClipDistance}) +0:69 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out 1-element array of float gl_ClipDistance}) +0:69 Constant: +0:69 4 (const int) +0:69 Constant: +0:69 1 (const int) +0:71 Barrier (void) +0:91 Function Definition: foop( (void) +0:91 Function Parameters: 0:? Sequence -0:68 multiply second child into first child (3-component vector of float) -0:68 'pv3' (3-component vector of float) -0:68 'pv3' (3-component vector of float) -0:69 move second child to first child (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 Function Call: fma(vf3;vf3;vf3; (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:69 'pv3' (3-component vector of float) -0:70 move second child to first child (double) -0:70 'd' (double) -0:70 Function Call: fma(d1;d1;d1; (double) -0:70 'd' (double) -0:70 'd' (double) -0:70 'd' (double) +0:95 multiply second child into first child (3-component vector of float) +0:95 'pv3' (3-component vector of float) +0:95 'pv3' (3-component vector of float) +0:96 move second child to first child (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 Function Call: fma(vf3;vf3;vf3; (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:96 'pv3' (3-component vector of float) +0:97 move second child to first child (double) +0:97 'd' (double) +0:97 Function Call: fma(d1;d1;d1; (double) +0:97 'd' (double) +0:97 'd' (double) +0:97 'd' (double) 0:? Linker Objects 0:? 'gl_out' (out 4-element array of block{out 4-component vector of float gl_Position, out float gl_PointSize, out 1-element array of float gl_ClipDistance}) 0:? 'outa' (4-element array of int) diff --git a/Test/baseResults/430.comp.out b/Test/baseResults/430.comp.out index b1fed46..0453641 100644 --- a/Test/baseResults/430.comp.out +++ b/Test/baseResults/430.comp.out @@ -3,17 +3,17 @@ Warning, version 430 is not yet complete; most version-specific features are pre ERROR: 0:4: 'local_size' : cannot change previously set size ERROR: 0:5: 'local_size' : too large; see gl_MaxComputeWorkGroupSize ERROR: 0:23: 'values' : only the last member of a buffer block can be run-time sized -ERROR: 0:39: 'in' : global storage input qualifier cannot be used in a compute shader -ERROR: 0:39: 'location qualifier on input' : not supported in this stage: compute -ERROR: 0:40: 'in' : global storage input qualifier cannot be used in a compute shader -ERROR: 0:41: 'out' : global storage output qualifier cannot be used in a compute shader -ERROR: 0:44: 'shared' : cannot apply layout qualifiers to a shared variable -ERROR: 0:44: 'location' : can only appy to uniform, buffer, in, or out storage qualifiers -ERROR: 0:45: 'shared' : cannot initialize this type of qualifier -ERROR: 0:47: 'local_size' : can only apply to 'in' -ERROR: 0:47: 'local_size' : can only apply to 'in' -ERROR: 0:47: 'local_size' : can only apply to 'in' -ERROR: 0:61: 'assign' : l-value required "ro" (can't modify a readonly buffer) +ERROR: 0:43: 'in' : global storage input qualifier cannot be used in a compute shader +ERROR: 0:43: 'location qualifier on input' : not supported in this stage: compute +ERROR: 0:44: 'in' : global storage input qualifier cannot be used in a compute shader +ERROR: 0:45: 'out' : global storage output qualifier cannot be used in a compute shader +ERROR: 0:48: 'shared' : cannot apply layout qualifiers to a shared variable +ERROR: 0:48: 'location' : can only appy to uniform, buffer, in, or out storage qualifiers +ERROR: 0:49: 'shared' : cannot initialize this type of qualifier +ERROR: 0:51: 'local_size' : can only apply to 'in' +ERROR: 0:51: 'local_size' : can only apply to 'in' +ERROR: 0:51: 'local_size' : can only apply to 'in' +ERROR: 0:65: 'assign' : l-value required "ro" (can't modify a readonly buffer) ERROR: 14 compilation errors. No code generated. @@ -42,24 +42,33 @@ ERROR: node is still EOpNull! 0:36 Constant: 0:36 1 (const uint) 0:36 'gl_LocalInvocationIndex' (in uint) -0:59 Function Definition: foo( (void) -0:59 Function Parameters: -0:61 Sequence -0:61 move second child to first child (float) -0:61 direct index (layout(column_major shared ) float) -0:61 values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of float) -0:61 'ro' (layout(column_major shared ) readonly buffer block{layout(column_major shared ) buffer int value, layout(column_major shared ) buffer implicitly-sized array of float values}) -0:61 Constant: -0:61 1 (const int) -0:61 Constant: -0:61 2 (const int) -0:61 Constant: -0:61 4.700000 -0:62 array length (int) -0:62 values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of float) -0:62 'ro' (layout(column_major shared ) readonly buffer block{layout(column_major shared ) buffer int value, layout(column_major shared ) buffer implicitly-sized array of float values}) -0:62 Constant: -0:62 1 (const int) +0:39 Test condition and select (void) +0:39 Condition +0:39 Compare Greater Than (bool) +0:39 'a' (int) +0:39 Constant: +0:39 10 (const int) +0:39 true case +0:40 Barrier (void) +0:63 Function Definition: foo( (void) +0:63 Function Parameters: +0:65 Sequence +0:65 move second child to first child (float) +0:65 direct index (layout(column_major shared ) float) +0:65 values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of float) +0:65 'ro' (layout(column_major shared ) readonly buffer block{layout(column_major shared ) buffer int value, layout(column_major shared ) buffer implicitly-sized array of float values}) +0:65 Constant: +0:65 1 (const int) +0:65 Constant: +0:65 2 (const int) +0:65 Constant: +0:65 4.700000 +0:66 array length (int) +0:66 values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of float) +0:66 'ro' (layout(column_major shared ) readonly buffer block{layout(column_major shared ) buffer int value, layout(column_major shared ) buffer implicitly-sized array of float values}) +0:66 Constant: +0:66 1 (const int) +0:67 Barrier (void) 0:? Linker Objects 0:? 'gl_WorkGroupSize' (const 3-component vector of uint) 0:? 2 (const uint) @@ -109,24 +118,33 @@ ERROR: node is still EOpNull! 0:36 Constant: 0:36 1 (const uint) 0:36 'gl_LocalInvocationIndex' (in uint) -0:59 Function Definition: foo( (void) -0:59 Function Parameters: -0:61 Sequence -0:61 move second child to first child (float) -0:61 direct index (layout(column_major shared ) float) -0:61 values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of float) -0:61 'ro' (layout(column_major shared ) readonly buffer block{layout(column_major shared ) buffer int value, layout(column_major shared ) buffer implicitly-sized array of float values}) -0:61 Constant: -0:61 1 (const int) -0:61 Constant: -0:61 2 (const int) -0:61 Constant: -0:61 4.700000 -0:62 array length (int) -0:62 values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of float) -0:62 'ro' (layout(column_major shared ) readonly buffer block{layout(column_major shared ) buffer int value, layout(column_major shared ) buffer implicitly-sized array of float values}) -0:62 Constant: -0:62 1 (const int) +0:39 Test condition and select (void) +0:39 Condition +0:39 Compare Greater Than (bool) +0:39 'a' (int) +0:39 Constant: +0:39 10 (const int) +0:39 true case +0:40 Barrier (void) +0:63 Function Definition: foo( (void) +0:63 Function Parameters: +0:65 Sequence +0:65 move second child to first child (float) +0:65 direct index (layout(column_major shared ) float) +0:65 values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of float) +0:65 'ro' (layout(column_major shared ) readonly buffer block{layout(column_major shared ) buffer int value, layout(column_major shared ) buffer implicitly-sized array of float values}) +0:65 Constant: +0:65 1 (const int) +0:65 Constant: +0:65 2 (const int) +0:65 Constant: +0:65 4.700000 +0:66 array length (int) +0:66 values: direct index for structure (layout(column_major shared ) buffer implicitly-sized array of float) +0:66 'ro' (layout(column_major shared ) readonly buffer block{layout(column_major shared ) buffer int value, layout(column_major shared ) buffer implicitly-sized array of float values}) +0:66 Constant: +0:66 1 (const int) +0:67 Barrier (void) 0:? Linker Objects 0:? 'gl_WorkGroupSize' (const 3-component vector of uint) 0:? 2 (const uint) diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index f67a6f5..0837553 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -51,7 +51,8 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, bool fc, EShMessages m) : intermediate(interm), symbolTable(symt), infoSink(is), language(L), version(v), profile(p), forwardCompatible(fc), messages(m), - contextPragma(true, false), loopNestingLevel(0), controlFlowNestingLevel(0), structNestingLevel(0), + contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), statementNestingLevel(0), + postMainReturn(false), tokensBeforeEOF(false), limits(resources.limits), currentScanner(0), numErrors(0), parsingBuiltins(pb), afterEOF(false), atomicUintOffsets(0), anyIndexLimits(false) @@ -915,7 +916,9 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(TSourceLoc loc, TFunct if (function.getType().getBasicType() != EbtVoid) error(loc, "", function.getType().getBasicTypeString().c_str(), "main function cannot return a value"); intermediate.addMainCount(); - } + inMain = true; + } else + inMain = false; // // New symbol table scope for body of function plus its arguments @@ -953,7 +956,9 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(TSourceLoc loc, TFunct } intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), loc); loopNestingLevel = 0; + statementNestingLevel = 0; controlFlowNestingLevel = 0; + postMainReturn = false; return paramNodes; } @@ -1045,6 +1050,7 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* funct op = fnCandidate->getBuiltInOp(); if (builtIn && op != EOpNull) { // A function call mapped to a built-in operation. + checkLocation(loc, op); result = intermediate.addBuiltInFunctionCall(loc, op, fnCandidate->getParamCount() == 1, arguments, fnCandidate->getType()); if (result == 0) { error(arguments->getLoc(), " wrong operand type", "Internal Error", @@ -1091,6 +1097,25 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* funct return result; } +// See if the operation is being done in an illegal location. +void TParseContext::checkLocation(TSourceLoc loc, TOperator op) +{ + switch (op) { + case EOpBarrier: + if (language == EShLangTessControl) { + if (controlFlowNestingLevel > 0) + error(loc, "tessellation control barrier() cannot be placed within flow control", "", ""); + if (! inMain) + error(loc, "tessellation control barrier() must be in main()", "", ""); + else if (postMainReturn) + error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", ""); + } + break; + default: + break; + } +} + // Finish processing object.length(). This started earlier in handleDotDereference(), where // the ".length" part was recognized and semantically checked, and finished here where the // function syntax "()" is recognized. diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 6b1e72f..388c16b 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -101,6 +101,7 @@ public: TFunction* handleFunctionDeclarator(TSourceLoc loc, TFunction& function, bool prototype); TIntermAggregate* handleFunctionDefinition(TSourceLoc, TFunction&); TIntermTyped* handleFunctionCall(TSourceLoc, TFunction*, TIntermNode*); + void checkLocation(TSourceLoc, TOperator); TIntermTyped* handleLengthMethod(TSourceLoc, TFunction*, TIntermNode*); void addInputArgumentConversions(const TFunction&, TIntermNode*&) const; TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const; @@ -245,9 +246,12 @@ public: struct TPragma contextPragma; int loopNestingLevel; // 0 if outside all loops int structNestingLevel; // 0 if outside blocks and structures - int controlFlowNestingLevel; // 0 if outside all flow control or compound statements; also counts compound statements + int controlFlowNestingLevel; // 0 if outside all flow control + int statementNestingLevel; // 0 if outside all flow control or compound statements TList switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting - TList switchLevel; // the controlFlowNestingLevel the current switch statement is at, which must match the level of its case statements + TList switchLevel; // the statementNestingLevel the current switch statement is at, which must match the level of its case statements + bool inMain; // if inside a function, true if the function is main + bool postMainReturn; // if inside a function, true if the function is main and this is after a return statement const TType* currentFunctionType; // the return type of the function that's currently being parsed bool functionReturnsValue; // true if a non-void function has a return const TString* blockName; diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index aa8d75d..bda83c5 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -2065,11 +2065,11 @@ compound_statement : LEFT_BRACE RIGHT_BRACE { $$ = 0; } | LEFT_BRACE { parseContext.symbolTable.push(); - ++parseContext.controlFlowNestingLevel; + ++parseContext.statementNestingLevel; } statement_list { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); - --parseContext.controlFlowNestingLevel; + --parseContext.statementNestingLevel; } RIGHT_BRACE { if ($3 && $3->getAsAggregate()) @@ -2084,13 +2084,21 @@ statement_no_new_scope ; statement_scoped - : compound_statement { $$ = $1; } + : { + ++parseContext.controlFlowNestingLevel; + } + compound_statement { + --parseContext.controlFlowNestingLevel; + $$ = $2; + } | { parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } simple_statement { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; $$ = $2; } @@ -2171,8 +2179,9 @@ switch_statement : SWITCH LEFT_PAREN expression RIGHT_PAREN { // start new switch sequence on the switch stack ++parseContext.controlFlowNestingLevel; + ++parseContext.statementNestingLevel; parseContext.switchSequenceStack.push_back(new TIntermSequence); - parseContext.switchLevel.push_back(parseContext.controlFlowNestingLevel); + parseContext.switchLevel.push_back(parseContext.statementNestingLevel); parseContext.symbolTable.push(); } LEFT_BRACE switch_statement_list RIGHT_BRACE { @@ -2181,6 +2190,7 @@ switch_statement parseContext.switchSequenceStack.pop_back(); parseContext.switchLevel.pop_back(); parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } ; @@ -2199,7 +2209,7 @@ case_label $$ = 0; if (parseContext.switchLevel.size() == 0) parseContext.error($1.loc, "cannot appear outside switch statement", "case", ""); - else if (parseContext.switchLevel.back() != parseContext.controlFlowNestingLevel) + else if (parseContext.switchLevel.back() != parseContext.statementNestingLevel) parseContext.error($1.loc, "cannot be nested inside control flow", "case", ""); else { parseContext.constantValueCheck($2, "case"); @@ -2211,7 +2221,7 @@ case_label $$ = 0; if (parseContext.switchLevel.size() == 0) parseContext.error($1.loc, "cannot appear outside switch statement", "default", ""); - else if (parseContext.switchLevel.back() != parseContext.controlFlowNestingLevel) + else if (parseContext.switchLevel.back() != parseContext.statementNestingLevel) parseContext.error($1.loc, "cannot be nested inside control flow", "default", ""); else $$ = parseContext.intermediate.addBranch(EOpDefault, $1.loc); @@ -2224,16 +2234,19 @@ iteration_statement parseContext.error($1.loc, "while loops not available", "limitation", ""); parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } condition RIGHT_PAREN statement_no_new_scope { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); $$ = parseContext.intermediate.addLoop($6, $4, 0, true, $1.loc); --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } | DO { ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { @@ -2244,11 +2257,13 @@ iteration_statement $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc); --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } | FOR LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { @@ -2260,6 +2275,7 @@ iteration_statement $$ = parseContext.intermediate.growAggregate($$, forLoop, $1.loc); $$->getAsAggregate()->setOperator(EOpSequence); --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } ; @@ -2308,6 +2324,8 @@ jump_statement $$ = parseContext.intermediate.addBranch(EOpReturn, $1.loc); if (parseContext.currentFunctionType->getBasicType() != EbtVoid) parseContext.error($1.loc, "non-void function must return a value", "return", ""); + if (parseContext.inMain) + parseContext.postMainReturn = true; } | RETURN expression SEMICOLON { parseContext.functionReturnsValue = true; -- 2.7.4