Fix memory corruption SpirvShaderKey::SpecializationInfo

SpecializationInfo was default copy-constructed / assigned, and held a raw pointer to the copy of the VkSpecializationInfo. This struct was deleted in the destructor, trashing any other copies.

Fixes undefined behavior and crashes of a few Vulkan samples.

Bug b/123588002

Change-Id: I7adcec2d51bc357ef5bcee1ec6bdafe9ecd208a7
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/34454
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
diff --git a/src/Vulkan/VkPipelineCache.hpp b/src/Vulkan/VkPipelineCache.hpp
index ffdfc2c..5195dbe 100644
--- a/src/Vulkan/VkPipelineCache.hpp
+++ b/src/Vulkan/VkPipelineCache.hpp
@@ -52,14 +52,18 @@
 		struct SpecializationInfo
 		{
 			SpecializationInfo(const VkSpecializationInfo* specializationInfo);
-			~SpecializationInfo();
 
 			bool operator<(const SpecializationInfo& specializationInfo) const;
 
-			VkSpecializationInfo* get() const { return info; }
+			const VkSpecializationInfo* get() const { return info.get(); }
 
 		private:
-			VkSpecializationInfo* info = nullptr;
+			struct Deleter
+			{
+				void operator()(VkSpecializationInfo*) const;
+			};
+
+			std::shared_ptr<VkSpecializationInfo> info;
 		};
 
 		SpirvShaderKey(const VkShaderStageFlagBits pipelineStage,
@@ -97,9 +101,9 @@
 			shader(shader), layout(layout)
 		{}
 
-		bool operator<(const ComputeProgramKey &other) const

-		{

-			return (shader < other.shader) || (layout < other.layout);

+		bool operator<(const ComputeProgramKey &other) const
+		{
+			return (shader < other.shader) || (layout < other.layout);
 		}
 
 		const sw::SpirvShader* getShader() const { return shader; }