From 26a93a530bd54c47ca012955820acaa6108cc0ff Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Wed, 21 Feb 2024 15:57:44 -0500 Subject: [PATCH] Use `std::deque` for assertions Also fix a memory leak --- include/link/patch.hpp | 8 +++----- src/link/object.cpp | 19 ++++++++++--------- src/link/patch.cpp | 35 +++++++++++++++-------------------- 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/include/link/patch.hpp b/include/link/patch.hpp index e8273dcd..1b197d0d 100644 --- a/include/link/patch.hpp +++ b/include/link/patch.hpp @@ -4,6 +4,7 @@ #ifndef RGBDS_LINK_PATCH_H #define RGBDS_LINK_PATCH_H +#include #include #include "link/section.hpp" @@ -11,20 +12,17 @@ #include "linkdefs.hpp" struct Assertion { - struct Patch patch; - // enum AssertionType type; The `patch`'s field is instead re-used + struct Patch patch; // Also used for its `.type` char *message; // This would be redundant with `.section->fileSymbols`... but `section` is sometimes NULL! struct Symbol **fileSymbols; - - struct Assertion *next; }; /* * Checks all assertions * @return true if assertion failed */ -void patch_CheckAssertions(struct Assertion *assertion); +void patch_CheckAssertions(std::deque &assertions); /* * Applies all SECTIONs' patches to them diff --git a/src/link/object.cpp b/src/link/object.cpp index 12c847b7..9dc59213 100644 --- a/src/link/object.cpp +++ b/src/link/object.cpp @@ -34,7 +34,7 @@ static struct FileStackNodes { struct FileStackNode *nodes; uint32_t nbNodes; } *nodes; -static struct Assertion *assertions; +static std::deque assertions; // Helper functions for reading object files @@ -617,15 +617,11 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) tryReadlong(nbAsserts, file, "%s: Cannot read number of assertions: %s", fileName); verbosePrint("Reading %" PRIu32 " assertions...\n", nbAsserts); for (uint32_t i = 0; i < nbAsserts; i++) { - struct Assertion *assertion = (struct Assertion *)malloc(sizeof(*assertion)); + struct Assertion &assertion = assertions.emplace_front(); - if (!assertion) - err("%s: Failed to create new assertion", fileName); - readAssertion(file, assertion, fileName, i, nodes[fileID].nodes); - linkPatchToPCSect(&assertion->patch, fileSections); - assertion->fileSymbols = fileSymbols; - assertion->next = assertions; - assertions = assertion; + readAssertion(file, &assertion, fileName, i, nodes[fileID].nodes); + linkPatchToPCSect(&assertion.patch, fileSections); + assertion.fileSymbols = fileSymbols; } free(fileSections); @@ -706,4 +702,9 @@ void obj_Cleanup(void) freeSymbol(list.symbolList[i]); free(list.symbolList); } + + for (struct Assertion &assert : assertions) { + free(assert.patch.rpnExpression); + free(assert.message); + } } diff --git a/src/link/patch.cpp b/src/link/patch.cpp index 66291c88..4a242260 100644 --- a/src/link/patch.cpp +++ b/src/link/patch.cpp @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: MIT */ #include +#include #include #include #include @@ -456,45 +457,39 @@ static int32_t computeRPNExpr(struct Patch const *patch, #undef popRPN } -void patch_CheckAssertions(struct Assertion *assert) +void patch_CheckAssertions(std::deque &assertions) { verbosePrint("Checking assertions...\n"); initRPNStack(); - while (assert) { - int32_t value = computeRPNExpr(&assert->patch, - (struct Symbol const * const *)assert->fileSymbols); - enum AssertionType type = (enum AssertionType)assert->patch.type; + for (struct Assertion &assert : assertions) { + int32_t value = computeRPNExpr(&assert.patch, + (struct Symbol const * const *)assert.fileSymbols); + enum AssertionType type = (enum AssertionType)assert.patch.type; if (!isError && !value) { switch (type) { case ASSERT_FATAL: - fatal(assert->patch.src, assert->patch.lineNo, "%s", - assert->message[0] ? assert->message + fatal(assert.patch.src, assert.patch.lineNo, "%s", + assert.message[0] ? assert.message : "assert failure"); case ASSERT_ERROR: - error(assert->patch.src, assert->patch.lineNo, "%s", - assert->message[0] ? assert->message + error(assert.patch.src, assert.patch.lineNo, "%s", + assert.message[0] ? assert.message : "assert failure"); break; case ASSERT_WARN: - warning(assert->patch.src, assert->patch.lineNo, "%s", - assert->message[0] ? assert->message + warning(assert.patch.src, assert.patch.lineNo, "%s", + assert.message[0] ? assert.message : "assert failure"); break; } } else if (isError && type == ASSERT_FATAL) { - fatal(assert->patch.src, assert->patch.lineNo, + fatal(assert.patch.src, assert.patch.lineNo, "Failed to evaluate assertion%s%s", - assert->message[0] ? ": " : "", - assert->message); + assert.message[0] ? ": " : "", + assert.message); } - struct Assertion *next = assert->next; - - free(assert->patch.rpnExpression); - free(assert->message); - free(assert); - assert = next; } freeRPNStack();