Make validation function more robust
authorBoris Zanin <boris.zanin@mobica.com>
Thu, 14 Mar 2019 14:58:34 +0000 (15:58 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Fri, 17 May 2019 11:32:42 +0000 (07:32 -0400)
This change modifies validateSpirV function.
Code should expect spvBinaryToText can leave some
parameters uninitialized (at least pText).
Also expect some other functions to return
uninitialized results (spvValidatorOptionsCreate,
spvContextCreate).

Affects:
 * dEQP-VK.*

Components: Framework, Vulkan

VK-GL-CTS issue: 1645

Change-Id: Ia5af2c5451d33247af2b8934fe4e5391badc8163

external/vulkancts/framework/vulkan/vkSpirVAsm.cpp

index 332072b..28b84bd 100644 (file)
@@ -147,14 +147,22 @@ void disassembleSpirV (size_t binarySizeInWords, const deUint32* binary, std::os
 
 bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostream* infoLog, const SpirvValidatorOptions &val_options)
 {
-       const spv_context       context         = spvContextCreate(mapVulkanVersionToSpirvToolsEnv(val_options.vulkanVersion));
-       spv_diagnostic          diagnostic      = DE_NULL;
+       const spv_context               context         = spvContextCreate(mapVulkanVersionToSpirvToolsEnv(val_options.vulkanVersion));
+       spv_diagnostic                  diagnostic      = DE_NULL;
+       spv_validator_options   options         = DE_NULL;
+       spv_text                                disasmText      = DE_NULL;
+
+       if (!context)
+               throw std::bad_alloc();
 
        try
        {
                spv_const_binary_t              cbinary = { binary, binarySizeInWords };
 
-               spv_validator_options options = spvValidatorOptionsCreate();
+               options = spvValidatorOptionsCreate();
+
+               if (options == DE_NULL)
+                       throw std::bad_alloc();
 
                switch (val_options.blockLayout)
                {
@@ -177,20 +185,27 @@ bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostre
                const spv_result_t              valid   = spvValidateWithOptions(context, options, &cbinary, &diagnostic);
                const bool                              passed  = (valid == SPV_SUCCESS);
 
-               if (diagnostic)
+               *infoLog << "Validation " << (passed ? "PASSED: " : "FAILED: ");
+
+               if (diagnostic && diagnostic->error)
                {
                        // Print the diagnostic whether validation passes or fails.
                        // In theory we could get a warning even in the pass case, but there are no cases
                        // like that now.
-                       *infoLog << "Validation " << (passed ? "PASSED: " : "FAILED: ") << diagnostic->error << "\n";
+                       *infoLog << diagnostic->error << "\n";
 
-                       spv_text text;
-                       spvBinaryToText(context, binary, binarySizeInWords, SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT, &text, DE_NULL);
+                       const deUint32          disasmOptions   = SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES
+                                                                                               | SPV_BINARY_TO_TEXT_OPTION_INDENT;
+                       const spv_result_t      disasmResult    = spvBinaryToText(context, binary, binarySizeInWords, disasmOptions, &disasmText, DE_NULL);
 
-                       *infoLog << text->str << "\n";
-                       spvTextDestroy(text);
+                       if (disasmResult != SPV_SUCCESS)
+                               *infoLog << "Disassembly failed with code: " << de::toString(disasmResult) << "\n";
+
+                       if (disasmText != DE_NULL)
+                               *infoLog << disasmText->str << "\n";
                }
 
+               spvTextDestroy(disasmText);
                spvValidatorOptionsDestroy(options);
                spvDiagnosticDestroy(diagnostic);
                spvContextDestroy(context);
@@ -199,6 +214,8 @@ bool validateSpirV (size_t binarySizeInWords, const deUint32* binary, std::ostre
        }
        catch (...)
        {
+               spvTextDestroy(disasmText);
+               spvValidatorOptionsDestroy(options);
                spvDiagnosticDestroy(diagnostic);
                spvContextDestroy(context);