diff --git a/reference/opt/shaders-msl/frag/private-variable-prototype-declaration.frag b/reference/opt/shaders-msl/frag/private-variable-prototype-declaration.frag new file mode 100644 index 00000000..1e9dc12d --- /dev/null +++ b/reference/opt/shaders-msl/frag/private-variable-prototype-declaration.frag @@ -0,0 +1,17 @@ +#include +#include + +using namespace metal; + +struct main0_out +{ + float3 FragColor [[color(0)]]; +}; + +fragment main0_out main0() +{ + main0_out out = {}; + out.FragColor = float3(1.0); + return out; +} + diff --git a/reference/shaders-msl/frag/private-variable-prototype-declaration.frag b/reference/shaders-msl/frag/private-variable-prototype-declaration.frag new file mode 100644 index 00000000..d014623b --- /dev/null +++ b/reference/shaders-msl/frag/private-variable-prototype-declaration.frag @@ -0,0 +1,39 @@ +#pragma clang diagnostic ignored "-Wmissing-prototypes" + +#include +#include + +using namespace metal; + +struct AStruct +{ + float4 foobar; +}; + +struct main0_out +{ + float3 FragColor [[color(0)]]; +}; + +void someFunction(thread AStruct& s) +{ + s.foobar = float4(1.0); +} + +void otherFunction(thread float3& global_variable) +{ + global_variable = float3(1.0); +} + +fragment main0_out main0() +{ + main0_out out = {}; + AStruct param; + someFunction(param); + AStruct inputs = param; + float3 global_variable; + otherFunction(global_variable); + out.FragColor = global_variable; + return out; +} + diff --git a/shaders-msl/frag/private-variable-prototype-declaration.frag b/shaders-msl/frag/private-variable-prototype-declaration.frag new file mode 100644 index 00000000..7d2bba5a --- /dev/null +++ b/shaders-msl/frag/private-variable-prototype-declaration.frag @@ -0,0 +1,20 @@ +#version 450 + +struct AStruct { vec4 foobar; }; + +void someFunction(out AStruct s) { s.foobar = vec4(1.0); } + +highp vec3 global_variable; + +void otherFunction() { + global_variable = vec3(1.0); +} + +layout(location = 0) out vec3 FragColor; + +void main() { + AStruct inputs; + someFunction(inputs); + otherFunction(); + FragColor = global_variable; +} diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 6881227b..b4d888ad 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -10660,6 +10660,14 @@ void CompilerGLSL::emit_function(SPIRFunction &func, const Bitset &return_flags) end_scope(); processing_entry_point = false; statement(""); + + // Make sure deferred declaration state for local variables is cleared when we are done with function. + // We risk declaring Private/Workgroup variables in places we are not supposed to otherwise. + for (auto &v : func.local_variables) + { + auto &var = get(v); + var.deferred_declaration = false; + } } void CompilerGLSL::emit_fixup()