Fix leaks in tests (#2295)
Generally, a test fixture in a method that can generate a binary
should release any previously cached binary. Similarly for diagnostics.
diff --git a/test/binary_parse_test.cpp b/test/binary_parse_test.cpp
index dfff79d..749e12f 100644
--- a/test/binary_parse_test.cpp
+++ b/test/binary_parse_test.cpp
@@ -197,6 +197,8 @@
class BinaryParseTest : public spvtest::TextToBinaryTestBase<::testing::Test> {
protected:
+ ~BinaryParseTest() { spvDiagnosticDestroy(diagnostic_); }
+
void Parse(const SpirvVector& words, spv_result_t expected_result,
bool flip_words = false) {
SpirvVector flipped_words(words);
diff --git a/test/binary_to_text_test.cpp b/test/binary_to_text_test.cpp
index 016041f..00ac86b 100644
--- a/test/binary_to_text_test.cpp
+++ b/test/binary_to_text_test.cpp
@@ -34,8 +34,12 @@
class BinaryToText : public ::testing::Test {
public:
- BinaryToText() : context(spvContextCreate(SPV_ENV_UNIVERSAL_1_0)) {}
- ~BinaryToText() { spvContextDestroy(context); }
+ BinaryToText()
+ : context(spvContextCreate(SPV_ENV_UNIVERSAL_1_0)), binary(nullptr) {}
+ ~BinaryToText() {
+ spvBinaryDestroy(binary);
+ spvContextDestroy(context);
+ }
virtual void SetUp() {
const char* textStr = R"(
@@ -63,17 +67,20 @@
spv_diagnostic diagnostic = nullptr;
spv_result_t error =
spvTextToBinary(context, text.str, text.length, &binary, &diagnostic);
- if (error) {
- spvDiagnosticPrint(diagnostic);
- spvDiagnosticDestroy(diagnostic);
- ASSERT_EQ(SPV_SUCCESS, error);
- }
+ spvDiagnosticPrint(diagnostic);
+ spvDiagnosticDestroy(diagnostic);
+ ASSERT_EQ(SPV_SUCCESS, error);
}
- virtual void TearDown() { spvBinaryDestroy(binary); }
+ virtual void TearDown() {
+ spvBinaryDestroy(binary);
+ binary = nullptr;
+ }
// Compiles the given assembly text, and saves it into 'binary'.
void CompileSuccessfully(std::string text) {
+ spvBinaryDestroy(binary);
+ binary = nullptr;
spv_diagnostic diagnostic = nullptr;
EXPECT_EQ(SPV_SUCCESS, spvTextToBinary(context, text.c_str(), text.size(),
&binary, &diagnostic));
diff --git a/test/ext_inst.glsl_test.cpp b/test/ext_inst.glsl_test.cpp
index 991c487..f52337c 100644
--- a/test/ext_inst.glsl_test.cpp
+++ b/test/ext_inst.glsl_test.cpp
@@ -61,7 +61,7 @@
; Generator: Khronos SPIR-V Tools Assembler; 0
; Bound: 9
; Schema: 0)";
- spv_binary binary;
+ spv_binary binary = nullptr;
spv_diagnostic diagnostic;
spv_result_t error = spvTextToBinary(context, spirv.c_str(), spirv.size(),
&binary, &diagnostic);
@@ -102,6 +102,7 @@
}
EXPECT_EQ(spirv_header + spirv, output_text->str);
spvTextDestroy(output_text);
+ spvBinaryDestroy(binary);
spvContextDestroy(context);
}
diff --git a/test/test_fixture.h b/test/test_fixture.h
index e85015c..436993e 100644
--- a/test/test_fixture.h
+++ b/test/test_fixture.h
@@ -61,6 +61,8 @@
// compilation success. Returns the compiled code.
SpirvVector CompileSuccessfully(const std::string& txt,
spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
+ DestroyBinary();
+ DestroyDiagnostic();
spv_result_t status =
spvTextToBinary(ScopedContext(env).context, txt.c_str(), txt.size(),
&binary, &diagnostic);
@@ -79,6 +81,8 @@
// Returns the error message(s).
std::string CompileFailure(const std::string& txt,
spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
+ DestroyBinary();
+ DestroyDiagnostic();
EXPECT_NE(SPV_SUCCESS,
spvTextToBinary(ScopedContext(env).context, txt.c_str(),
txt.size(), &binary, &diagnostic))
@@ -94,6 +98,7 @@
uint32_t disassemble_options = SPV_BINARY_TO_TEXT_OPTION_NONE,
spv_target_env env = SPV_ENV_UNIVERSAL_1_0) {
DestroyBinary();
+ DestroyDiagnostic();
ScopedContext context(env);
disassemble_options |= SPV_BINARY_TO_TEXT_OPTION_NO_HEADER;
spv_result_t error = spvTextToBinary(context.context, txt.c_str(),
@@ -126,6 +131,8 @@
// Returns the error message.
std::string EncodeSuccessfullyDecodeFailed(
const std::string& txt, const SpirvVector& words_to_append) {
+ DestroyBinary();
+ DestroyDiagnostic();
SpirvVector code =
spvtest::Concatenate({CompileSuccessfully(txt), words_to_append});
@@ -169,6 +176,12 @@
binary = nullptr;
}
+ // Destroys the diagnostic, if it exists.
+ void DestroyDiagnostic() {
+ spvDiagnosticDestroy(diagnostic);
+ diagnostic = nullptr;
+ }
+
spv_diagnostic diagnostic;
std::string textString;
diff --git a/test/val/val_fixtures.h b/test/val/val_fixtures.h
index 73a0cc6..69bc9d8 100644
--- a/test/val/val_fixtures.h
+++ b/test/val/val_fixtures.h
@@ -56,6 +56,18 @@
spv_result_t ValidateAndRetrieveValidationState(
spv_target_env env = SPV_ENV_UNIVERSAL_1_0);
+ // Destroys the stored binary.
+ void DestroyBinary() {
+ spvBinaryDestroy(binary_);
+ binary_ = nullptr;
+ }
+
+ // Destroys the stored diagnostic.
+ void DestroyDiagnostic() {
+ spvDiagnosticDestroy(diagnostic_);
+ diagnostic_ = nullptr;
+ }
+
std::string getDiagnosticString();
spv_position_t getErrorPosition();
spv_validator_options getValidatorOptions();
@@ -67,7 +79,7 @@
};
template <typename T>
-ValidateBase<T>::ValidateBase() : binary_(), diagnostic_() {
+ValidateBase<T>::ValidateBase() : binary_(nullptr), diagnostic_(nullptr) {
// Initialize to default command line options. Different tests can then
// specialize specific options as necessary.
options_ = spvValidatorOptionsCreate();
@@ -83,14 +95,15 @@
if (diagnostic_) {
spvDiagnosticPrint(diagnostic_);
}
- spvDiagnosticDestroy(diagnostic_);
- spvBinaryDestroy(binary_);
+ DestroyBinary();
+ DestroyDiagnostic();
spvValidatorOptionsDestroy(options_);
}
template <typename T>
void ValidateBase<T>::CompileSuccessfully(std::string code,
spv_target_env env) {
+ DestroyBinary();
spv_diagnostic diagnostic = nullptr;
ASSERT_EQ(SPV_SUCCESS,
spvTextToBinary(ScopedContext(env).context, code.c_str(),
@@ -98,6 +111,7 @@
<< "ERROR: " << diagnostic->error
<< "\nSPIR-V could not be compiled into binary:\n"
<< code;
+ spvDiagnosticDestroy(diagnostic);
}
template <typename T>
@@ -110,6 +124,7 @@
template <typename T>
spv_result_t ValidateBase<T>::ValidateInstructions(spv_target_env env) {
+ DestroyDiagnostic();
return spvValidateWithOptions(ScopedContext(env).context, options_,
get_const_binary(), &diagnostic_);
}
@@ -117,6 +132,7 @@
template <typename T>
spv_result_t ValidateBase<T>::ValidateAndRetrieveValidationState(
spv_target_env env) {
+ DestroyDiagnostic();
return spvtools::val::ValidateBinaryAndKeepValidationState(
ScopedContext(env).context, options_, get_const_binary()->code,
get_const_binary()->wordCount, &diagnostic_, &vstate_);
diff --git a/test/val/val_id_test.cpp b/test/val/val_id_test.cpp
index 25fac88..a09761e 100644
--- a/test/val/val_id_test.cpp
+++ b/test/val/val_id_test.cpp
@@ -780,6 +780,8 @@
// Runs spvValidate() on v, printing any errors via spvDiagnosticPrint().
spv_result_t Val(const SpirvVector& v, const std::string& expected_err = "") {
spv_const_binary_t cbinary{v.data(), v.size()};
+ spvDiagnosticDestroy(diagnostic_);
+ diagnostic_ = nullptr;
const auto status =
spvValidate(ScopedContext().context, &cbinary, &diagnostic_);
if (status != SPV_SUCCESS) {