From 21682e8814ae597c5d4b0c1ec18cce0421aceb3f Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Tue, 7 Jul 2026 02:19:37 -0400 Subject: [PATCH] Consistently handle negative shifted macro args (#2014) Negative macro arguments count from the end, i.e. `\<-1>` is equivalent to `\<_NARG>`, even after `shift`ing them. Negative arguments cannot be used to access shifted values. --- include/asm/macro.hpp | 2 +- src/asm/macro.cpp | 26 ++++++++++++++++-------- test/asm/negative-shifted-macro-args.asm | 22 ++++++++++++++++++++ test/asm/negative-shifted-macro-args.err | 19 +++++++++++++++++ test/asm/negative-shifted-macro-args.out | 13 ++++++++++++ 5 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 test/asm/negative-shifted-macro-args.asm create mode 100644 test/asm/negative-shifted-macro-args.err create mode 100644 test/asm/negative-shifted-macro-args.out diff --git a/include/asm/macro.hpp b/include/asm/macro.hpp index c18b9de3..f12edea6 100644 --- a/include/asm/macro.hpp +++ b/include/asm/macro.hpp @@ -13,7 +13,7 @@ struct MacroArgs { std::vector> args; uint32_t nbArgs() const { return args.size() - shift; } - std::shared_ptr getArg(int32_t i) const; + std::shared_ptr getArg(int32_t num) const; std::shared_ptr getAllArgs() const; void appendArg(std::shared_ptr arg); diff --git a/src/asm/macro.cpp b/src/asm/macro.cpp index cc314280..b4999288 100644 --- a/src/asm/macro.cpp +++ b/src/asm/macro.cpp @@ -8,18 +8,26 @@ #include #include +#include "helpers.hpp" // assume + #include "asm/warning.hpp" -std::shared_ptr MacroArgs::getArg(int32_t i) const { - // Bracketed macro arguments adjust negative indexes such that -1 is the last argument. - if (i < 0) { - i += args.size() + 1; +std::shared_ptr MacroArgs::getArg(int32_t num) const { + assume(num != 0); + if (num > 0) { + // Macro arguments adjust 1-based indexes by the shift amount. + if (size_t i = num - 1 + shift; i < args.size()) { + return args[i]; + } + } else { + // Bracketed macro arguments adjust negative indexes such that -1 is the last argument. + if (num == INT32_MIN || static_cast(-num) > args.size()) { + return nullptr; + } else if (size_t i = args.size() - static_cast(-num); i >= shift) { + return args[i]; + } } - - int32_t realIndex = i + shift - 1; - - return realIndex < 0 || static_cast(realIndex) >= args.size() ? nullptr - : args[realIndex]; + return nullptr; } std::shared_ptr MacroArgs::getAllArgs() const { diff --git a/test/asm/negative-shifted-macro-args.asm b/test/asm/negative-shifted-macro-args.asm new file mode 100644 index 00000000..8cd4215c --- /dev/null +++ b/test/asm/negative-shifted-macro-args.asm @@ -0,0 +1,22 @@ +MACRO test + static_assert _NARG == 10 + println _NARG + println \1, \<10>, \<-1>, \<-10> + println \<999> + println \<-999> + shift 3 + println _NARG + println \1, \7, \<-1>, \<-7> + println \<8> + println \<-8> + println \<-999> + shift 7 + println _NARG + println \1 + println \<-1> + shift -10 + println _NARG + println \<-2_147_483_648> +ENDM + +test "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" diff --git a/test/asm/negative-shifted-macro-args.err b/test/asm/negative-shifted-macro-args.err new file mode 100644 index 00000000..1ec467d3 --- /dev/null +++ b/test/asm/negative-shifted-macro-args.err @@ -0,0 +1,19 @@ +error: Macro argument `\<999>` not defined + at negative-shifted-macro-args.asm::test(5) <- negative-shifted-macro-args.asm(22) +error: Macro argument `\<-999>` not defined + at negative-shifted-macro-args.asm::test(6) <- negative-shifted-macro-args.asm(22) +error: Macro argument `\<8>` not defined + at negative-shifted-macro-args.asm::test(10) <- negative-shifted-macro-args.asm(22) +error: Macro argument `\<-8>` not defined + at negative-shifted-macro-args.asm::test(11) <- negative-shifted-macro-args.asm(22) +error: Macro argument `\<-999>` not defined + at negative-shifted-macro-args.asm::test(12) <- negative-shifted-macro-args.asm(22) +error: Macro argument `\1` not defined + at negative-shifted-macro-args.asm::test(15) <- negative-shifted-macro-args.asm(22) +error: Macro argument `\<-1>` not defined + at negative-shifted-macro-args.asm::test(16) <- negative-shifted-macro-args.asm(22) +error: Number in bracketed macro argument is too large + at negative-shifted-macro-args.asm::test(19) <- negative-shifted-macro-args.asm(22) +error: syntax error, unexpected > + at negative-shifted-macro-args.asm::test(19) <- negative-shifted-macro-args.asm(22) +Assembly aborted with 9 errors diff --git a/test/asm/negative-shifted-macro-args.out b/test/asm/negative-shifted-macro-args.out new file mode 100644 index 00000000..4ae99772 --- /dev/null +++ b/test/asm/negative-shifted-macro-args.out @@ -0,0 +1,13 @@ +$A +ajja + + +$7 +djjd + + + +$0 + + +$A