mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 02:02:06 +00:00
Use loops instead of tail calls and musttail
gcc 15.2.1 20250813 complains "address of automatic variable can escape to `musttail` call" from `-Wmaybe-musttail-local-addr`, and guaranteeing tail-call optimization cross-platform is more trouble than it's worth.
This commit is contained in:
@@ -60,13 +60,4 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#endif
|
||||
|
||||
// gcc and clang have their own `musttail` attributes for tail recursion
|
||||
#if defined(__clang__) && __has_cpp_attribute(clang::musttail)
|
||||
#define MUSTTAIL [[clang::musttail]]
|
||||
#elif defined(__GNUC__) && __has_cpp_attribute(gnu::musttail)
|
||||
#define MUSTTAIL [[gnu::musttail]]
|
||||
#else
|
||||
#define MUSTTAIL
|
||||
#endif
|
||||
|
||||
#endif // RGBDS_PLATFORM_HPP
|
||||
|
||||
@@ -716,6 +716,7 @@ int LexerState::peekCharAhead() {
|
||||
static std::pair<Symbol const *, std::shared_ptr<std::string>> readInterpolation(size_t depth);
|
||||
|
||||
static int peek() {
|
||||
for (;;) {
|
||||
int c = lexerState->peekChar();
|
||||
|
||||
if (lexerState->expansionScanDistance > 0) {
|
||||
@@ -732,7 +733,6 @@ static int peek() {
|
||||
if (!isMacroChar(lexerState->peekCharAhead())) {
|
||||
return c;
|
||||
}
|
||||
|
||||
// If character is a macro arg char, do macro arg expansion
|
||||
shiftChar();
|
||||
if (std::shared_ptr<std::string> str = readMacroArg(); str) {
|
||||
@@ -743,19 +743,18 @@ static int peek() {
|
||||
// https://en.wikipedia.org/wiki/Painted_blue
|
||||
lexerState->expansionScanDistance += str->length();
|
||||
}
|
||||
|
||||
MUSTTAIL return peek();
|
||||
// Continue in the next iteration
|
||||
} else if (c == '{') {
|
||||
// If character is an open brace, do symbol interpolation
|
||||
shiftChar();
|
||||
if (auto interp = readInterpolation(0); interp.first && interp.second) {
|
||||
beginExpansion(interp.second, interp.first->name);
|
||||
}
|
||||
|
||||
MUSTTAIL return peek();
|
||||
// Continue in the next iteration
|
||||
} else {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void shiftChar() {
|
||||
@@ -1943,8 +1942,6 @@ static Token yylex_NORMAL() {
|
||||
if (Symbol const *sym = sym_FindExactSymbol(std::get<std::string>(token.value));
|
||||
sym && sym->type == SYM_EQUS) {
|
||||
beginExpansion(sym->getEqus(), sym->name);
|
||||
// We cannot do `MUSTTAIL return yylex_NORMAL();` because tail call optimization
|
||||
// requires the return value to be "trivially destructible", and `Token` is not.
|
||||
continue; // Restart, reading from the new buffer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "helpers.hpp"
|
||||
#include "itertools.hpp"
|
||||
#include "linkdefs.hpp"
|
||||
#include "platform.hpp" // MUSTTAIL
|
||||
#include "verbosity.hpp"
|
||||
|
||||
#include "link/main.hpp"
|
||||
@@ -119,6 +118,7 @@ static MemoryLocation getStartLocation(Section const §ion) {
|
||||
static std::optional<size_t> getPlacement(Section const §ion, MemoryLocation &location) {
|
||||
SectionTypeInfo const &typeInfo = sectionTypeInfo[section.type];
|
||||
|
||||
for (;;) {
|
||||
// Switch to the beginning of the next bank
|
||||
std::deque<FreeSpace> &bankMem = memory[section.type][location.bank - typeInfo.firstBank];
|
||||
size_t spaceIdx = 0;
|
||||
@@ -137,12 +137,11 @@ static std::optional<size_t> getPlacement(Section const §ion, MemoryLocation
|
||||
// Go to the next *possible* location
|
||||
if (section.isAddressFixed) {
|
||||
// If the address is fixed, there can be only one candidate block per bank;
|
||||
// if we already reached it, give up.
|
||||
if (location.address < section.org) {
|
||||
location.address = section.org;
|
||||
} else {
|
||||
break; // Try again in next bank
|
||||
// if we already reached it, give up and try again in the next bank.
|
||||
if (location.address >= section.org) {
|
||||
break;
|
||||
}
|
||||
location.address = section.org;
|
||||
} else if (section.isAlignFixed) {
|
||||
// Move to next aligned location
|
||||
// Move back to alignment boundary
|
||||
@@ -204,7 +203,8 @@ static std::optional<size_t> getPlacement(Section const §ion, MemoryLocation
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
MUSTTAIL return getPlacement(section, location);
|
||||
// Try again in the next iteration.
|
||||
}
|
||||
}
|
||||
|
||||
static std::string getSectionDescription(Section const §ion) {
|
||||
|
||||
Reference in New Issue
Block a user