mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Use standard attribute syntax instead of IBM __attribute__
Move format attrs to proper standard location For some reason, GCC 13 is more lax than earlier versions...
This commit is contained in:
@@ -62,7 +62,7 @@ void processWarningFlag(char const *flag);
|
|||||||
* Used to warn the user about problems that don't prevent the generation of
|
* Used to warn the user about problems that don't prevent the generation of
|
||||||
* valid code.
|
* valid code.
|
||||||
*/
|
*/
|
||||||
void warning(WarningID id, char const *fmt, ...) format_(printf, 2, 3);
|
[[gnu::format(printf, 2, 3)]] void warning(WarningID id, char const *fmt, ...);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used for errors that compromise the whole assembly process by affecting the
|
* Used for errors that compromise the whole assembly process by affecting the
|
||||||
@@ -71,7 +71,7 @@ void warning(WarningID id, char const *fmt, ...) format_(printf, 2, 3);
|
|||||||
* It is also used when the assembler goes into an invalid state (for example,
|
* It is also used when the assembler goes into an invalid state (for example,
|
||||||
* when it fails to allocate memory).
|
* when it fails to allocate memory).
|
||||||
*/
|
*/
|
||||||
[[noreturn]] void fatalerror(char const *fmt, ...) format_(printf, 1, 2);
|
[[gnu::format(printf, 1, 2), noreturn]] void fatalerror(char const *fmt, ...);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used for errors that make it impossible to assemble correctly, but don't
|
* Used for errors that make it impossible to assemble correctly, but don't
|
||||||
@@ -79,6 +79,6 @@ void warning(WarningID id, char const *fmt, ...) format_(printf, 2, 3);
|
|||||||
* get a list of all errors at the end, making it easier to fix all of them at
|
* get a list of all errors at the end, making it easier to fix all of them at
|
||||||
* once.
|
* once.
|
||||||
*/
|
*/
|
||||||
void error(char const *fmt, ...) format_(printf, 1, 2);
|
[[gnu::format(printf, 1, 2)]] void error(char const *fmt, ...);
|
||||||
|
|
||||||
#endif // WARNING_H
|
#endif // WARNING_H
|
||||||
|
|||||||
@@ -3,16 +3,15 @@
|
|||||||
#ifndef RGBDS_ERROR_H
|
#ifndef RGBDS_ERROR_H
|
||||||
#define RGBDS_ERROR_H
|
#define RGBDS_ERROR_H
|
||||||
|
|
||||||
#include "helpers.hpp"
|
|
||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
void warn(char const *fmt...) format_(printf, 1, 2);
|
[[gnu::format(printf, 1, 2)]] void warn(char const *fmt...);
|
||||||
void warnx(char const *fmt, ...) format_(printf, 1, 2);
|
[[gnu::format(printf, 1, 2)]] void warnx(char const *fmt, ...);
|
||||||
|
|
||||||
[[noreturn]] void err(char const *fmt, ...) format_(printf, 1, 2);
|
[[gnu::format(printf, 1, 2), noreturn]] void err(char const *fmt, ...);
|
||||||
[[noreturn]] void errx(char const *fmt, ...) format_(printf, 1, 2);
|
[[gnu::format(printf, 1, 2), noreturn]] void errx(char const *fmt, ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // RGBDS_ERROR_H
|
#endif // RGBDS_ERROR_H
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ struct Options {
|
|||||||
static constexpr uint8_t VERB_DEBUG = 4; // Internals are logged
|
static constexpr uint8_t VERB_DEBUG = 4; // Internals are logged
|
||||||
static constexpr uint8_t VERB_UNMAPPED = 5; // Unused so far
|
static constexpr uint8_t VERB_UNMAPPED = 5; // Unused so far
|
||||||
static constexpr uint8_t VERB_VVVVVV = 6; // What, can't I have a little fun?
|
static constexpr uint8_t VERB_VVVVVV = 6; // What, can't I have a little fun?
|
||||||
format_(printf, 3, 4) void verbosePrint(uint8_t level, char const *fmt, ...) const;
|
[[gnu::format(printf, 3, 4)]] void verbosePrint(uint8_t level, char const *fmt, ...) const;
|
||||||
|
|
||||||
mutable bool hasTransparentPixels = false;
|
mutable bool hasTransparentPixels = false;
|
||||||
uint8_t maxOpaqueColors() const { return nbColorsPerPal - hasTransparentPixels; }
|
uint8_t maxOpaqueColors() const { return nbColorsPerPal - hasTransparentPixels; }
|
||||||
@@ -73,11 +73,11 @@ extern Options options;
|
|||||||
/*
|
/*
|
||||||
* Prints a warning, and does not change the error count
|
* Prints a warning, and does not change the error count
|
||||||
*/
|
*/
|
||||||
void warning(char const *fmt, ...) format_(printf, 1, 2);
|
[[gnu::format(printf, 1, 2)]] void warning(char const *fmt, ...);
|
||||||
/*
|
/*
|
||||||
* Prints an error, and increments the error count
|
* Prints an error, and increments the error count
|
||||||
*/
|
*/
|
||||||
void error(char const *fmt, ...) format_(printf, 1, 2);
|
[[gnu::format(printf, 1, 2)]] void error(char const *fmt, ...);
|
||||||
/*
|
/*
|
||||||
* Prints an error, and increments the error count
|
* Prints an error, and increments the error count
|
||||||
* Does not take format arguments so `format_` and `-Wformat-security` won't complain about
|
* Does not take format arguments so `format_` and `-Wformat-security` won't complain about
|
||||||
@@ -87,7 +87,7 @@ void errorMessage(char const *msg);
|
|||||||
/*
|
/*
|
||||||
* Prints a fatal error, increments the error count, and gives up
|
* Prints a fatal error, increments the error count, and gives up
|
||||||
*/
|
*/
|
||||||
[[noreturn]] void fatal(char const *fmt, ...) format_(printf, 1, 2);
|
[[gnu::format(printf, 1, 2), noreturn]] void fatal(char const *fmt, ...);
|
||||||
|
|
||||||
struct Palette {
|
struct Palette {
|
||||||
// An array of 4 GBC-native (RGB555) colors
|
// An array of 4 GBC-native (RGB555) colors
|
||||||
|
|||||||
@@ -5,9 +5,6 @@
|
|||||||
|
|
||||||
// Ideally, we'd use `__has_attribute` and `__has_builtin`, but these were only introduced in GCC 9
|
// Ideally, we'd use `__has_attribute` and `__has_builtin`, but these were only introduced in GCC 9
|
||||||
#ifdef __GNUC__ // GCC or compatible
|
#ifdef __GNUC__ // GCC or compatible
|
||||||
#define format_(archetype, str_index, first_arg) \
|
|
||||||
__attribute__((format(archetype, str_index, first_arg)))
|
|
||||||
#define attr_(...) __attribute__((__VA_ARGS__))
|
|
||||||
// In release builds, define "unreachable" as such, but trap in debug builds
|
// In release builds, define "unreachable" as such, but trap in debug builds
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#define unreachable_ __builtin_unreachable
|
#define unreachable_ __builtin_unreachable
|
||||||
@@ -15,9 +12,6 @@
|
|||||||
#define unreachable_ __builtin_trap
|
#define unreachable_ __builtin_trap
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
// Unsupported, but no need to throw a fit
|
|
||||||
#define format_(archetype, str_index, first_arg)
|
|
||||||
#define attr_(...)
|
|
||||||
// This seems to generate similar code to __builtin_unreachable, despite different semantics
|
// This seems to generate similar code to __builtin_unreachable, despite different semantics
|
||||||
// Note that executing this is undefined behavior (declared [[noreturn]], but does return)
|
// Note that executing this is undefined behavior (declared [[noreturn]], but does return)
|
||||||
[[noreturn]] static inline void unreachable_() {
|
[[noreturn]] static inline void unreachable_() {
|
||||||
|
|||||||
@@ -59,10 +59,11 @@ struct FileStackNode {
|
|||||||
std::string const &dump(uint32_t curLineNo) const;
|
std::string const &dump(uint32_t curLineNo) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
void warning(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...)
|
[[gnu::format(printf, 3, 4)]] void
|
||||||
format_(printf, 3, 4);
|
warning(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...);
|
||||||
void error(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...) format_(printf, 3, 4);
|
[[gnu::format(printf, 3, 4)]] void
|
||||||
[[noreturn]] void fatal(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...)
|
error(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...);
|
||||||
format_(printf, 3, 4);
|
[[gnu::format(printf, 3, 4), noreturn]] void
|
||||||
|
fatal(FileStackNode const *where, uint32_t lineNo, char const *fmt, ...);
|
||||||
|
|
||||||
#endif // RGBDS_LINK_MAIN_H
|
#endif // RGBDS_LINK_MAIN_H
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ void FormatSpec::useCharacter(int c) {
|
|||||||
case '0':
|
case '0':
|
||||||
if (state < FORMAT_WIDTH)
|
if (state < FORMAT_WIDTH)
|
||||||
padZero = true;
|
padZero = true;
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
case '1':
|
case '1':
|
||||||
case '2':
|
case '2':
|
||||||
case '3':
|
case '3':
|
||||||
|
|||||||
@@ -864,7 +864,7 @@ static void discardBlockComment() {
|
|||||||
case '\r':
|
case '\r':
|
||||||
// Handle CRLF before nextLine() since shiftChar updates colNo
|
// Handle CRLF before nextLine() since shiftChar updates colNo
|
||||||
handleCRLF(c);
|
handleCRLF(c);
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
case '\n':
|
case '\n':
|
||||||
if (lexerState->expansions.empty())
|
if (lexerState->expansions.empty())
|
||||||
nextLine();
|
nextLine();
|
||||||
@@ -879,7 +879,7 @@ static void discardBlockComment() {
|
|||||||
shiftChar();
|
shiftChar();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1216,7 +1216,7 @@ static void appendEscapedSubstring(std::string &yylval, std::string const &str)
|
|||||||
case '"':
|
case '"':
|
||||||
case '{':
|
case '{':
|
||||||
yylval += '\\';
|
yylval += '\\';
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
default:
|
default:
|
||||||
yylval += c;
|
yylval += c;
|
||||||
break;
|
break;
|
||||||
@@ -1515,7 +1515,7 @@ static Token yylex_NORMAL() {
|
|||||||
|
|
||||||
case ';':
|
case ';':
|
||||||
discardComment();
|
discardComment();
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
break;
|
break;
|
||||||
@@ -1729,7 +1729,7 @@ static Token yylex_NORMAL() {
|
|||||||
|
|
||||||
case '\r':
|
case '\r':
|
||||||
handleCRLF(c);
|
handleCRLF(c);
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
case '\n':
|
case '\n':
|
||||||
return Token(T_(NEWLINE));
|
return Token(T_(NEWLINE));
|
||||||
|
|
||||||
@@ -1751,7 +1751,7 @@ static Token yylex_NORMAL() {
|
|||||||
shiftChar();
|
shiftChar();
|
||||||
return Token(T_(STRING), readString(true));
|
return Token(T_(STRING), readString(true));
|
||||||
}
|
}
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
|
|
||||||
// Handle identifiers... or report garbage characters
|
// Handle identifiers... or report garbage characters
|
||||||
|
|
||||||
@@ -1846,7 +1846,7 @@ static Token yylex_RAW() {
|
|||||||
case ';': // Comments inside macro args
|
case ';': // Comments inside macro args
|
||||||
discardComment();
|
discardComment();
|
||||||
c = peek();
|
c = peek();
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
case '\r': // End of line
|
case '\r': // End of line
|
||||||
case '\n':
|
case '\n':
|
||||||
case EOF:
|
case EOF:
|
||||||
@@ -1920,7 +1920,7 @@ backslash:
|
|||||||
error("Illegal character escape %s\n", printChar(c));
|
error("Illegal character escape %s\n", printChar(c));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
|
|
||||||
default: // Regular characters will just get copied
|
default: // Regular characters will just get copied
|
||||||
append:
|
append:
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ int main(int argc, char *argv[]) {
|
|||||||
// introduced to better match the `-I dir` option of gcc and clang.
|
// introduced to better match the `-I dir` option of gcc and clang.
|
||||||
case 'i':
|
case 'i':
|
||||||
warning(WARNING_OBSOLETE, "`-i` is deprecated; use `-I`\n");
|
warning(WARNING_OBSOLETE, "`-i` is deprecated; use `-I`\n");
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
case 'I':
|
case 'I':
|
||||||
fstk_AddIncludePath(musl_optarg);
|
fstk_AddIncludePath(musl_optarg);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ std::optional<std::string> currentLoadScope = std::nullopt;
|
|||||||
int32_t loadOffset; // Offset into the LOAD section's parent (see sect_GetOutputOffset)
|
int32_t loadOffset; // Offset into the LOAD section's parent (see sect_GetOutputOffset)
|
||||||
|
|
||||||
// A quick check to see if we have an initialized section
|
// A quick check to see if we have an initialized section
|
||||||
attr_(warn_unused_result) static bool checksection() {
|
[[nodiscard]] static bool checksection() {
|
||||||
if (currentSection)
|
if (currentSection)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ attr_(warn_unused_result) static bool checksection() {
|
|||||||
|
|
||||||
// A quick check to see if we have an initialized section that can contain
|
// A quick check to see if we have an initialized section that can contain
|
||||||
// this much initialized data
|
// this much initialized data
|
||||||
attr_(warn_unused_result) static bool checkcodesection() {
|
[[nodiscard]] static bool checkcodesection() {
|
||||||
if (!checksection())
|
if (!checksection())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ attr_(warn_unused_result) static bool checkcodesection() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr_(warn_unused_result) static bool checkSectionSize(Section const §, uint32_t size) {
|
[[nodiscard]] static bool checkSectionSize(Section const §, uint32_t size) {
|
||||||
uint32_t maxSize = sectionTypeInfo[sect.type].size;
|
uint32_t maxSize = sectionTypeInfo[sect.type].size;
|
||||||
|
|
||||||
// If the new size is reasonable, keep going
|
// If the new size is reasonable, keep going
|
||||||
@@ -88,7 +88,7 @@ attr_(warn_unused_result) static bool checkSectionSize(Section const §, uint
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the section has grown too much.
|
// Check if the section has grown too much.
|
||||||
attr_(warn_unused_result) static bool reserveSpace(uint32_t delta_size) {
|
[[nodiscard]] static bool reserveSpace(uint32_t delta_size) {
|
||||||
// This check is here to trap broken code that generates sections that are too big and to
|
// This check is here to trap broken code that generates sections that are too big and to
|
||||||
// prevent the assembler from generating huge object files or trying to allocate too much
|
// prevent the assembler from generating huge object files or trying to allocate too much
|
||||||
// memory.
|
// memory.
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ static void printUsage() {
|
|||||||
|
|
||||||
static uint8_t nbErrors;
|
static uint8_t nbErrors;
|
||||||
|
|
||||||
static format_(printf, 1, 2) void report(char const *fmt, ...) {
|
[[gnu::format(printf, 1, 2)]] static void report(char const *fmt, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
@@ -465,7 +465,7 @@ static MbcType parseMBC(char const *name) {
|
|||||||
static_assert(MBC1 + 2 == MBC1_RAM_BATTERY, "Enum sanity check failed!");
|
static_assert(MBC1 + 2 == MBC1_RAM_BATTERY, "Enum sanity check failed!");
|
||||||
static_assert(MMM01 + 1 == MMM01_RAM, "Enum sanity check failed!");
|
static_assert(MMM01 + 1 == MMM01_RAM, "Enum sanity check failed!");
|
||||||
static_assert(MMM01 + 2 == MMM01_RAM_BATTERY, "Enum sanity check failed!");
|
static_assert(MMM01 + 2 == MMM01_RAM_BATTERY, "Enum sanity check failed!");
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
case MBC1:
|
case MBC1:
|
||||||
case MMM01:
|
case MMM01:
|
||||||
if (features == RAM)
|
if (features == RAM)
|
||||||
|
|||||||
@@ -50,11 +50,11 @@ retry:
|
|||||||
do {
|
do {
|
||||||
firstChar = getc(file);
|
firstChar = getc(file);
|
||||||
} while (firstChar != EOF && firstChar != '\r' && firstChar != '\n');
|
} while (firstChar != EOF && firstChar != '\r' && firstChar != '\n');
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
case '\r':
|
case '\r':
|
||||||
if (firstChar == '\r' && getc(file) != '\n')
|
if (firstChar == '\r' && getc(file) != '\n')
|
||||||
consumeLF(where, lineNo, file);
|
consumeLF(where, lineNo, file);
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
case '\n':
|
case '\n':
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ retry:
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
case '\r':
|
case '\r':
|
||||||
consumeLF(where, lineNo, file);
|
consumeLF(where, lineNo, file);
|
||||||
// fallthrough
|
[[fallthrough]];
|
||||||
case '\n':
|
case '\n':
|
||||||
case EOF:
|
case EOF:
|
||||||
lineBuf.push_back('\0'); // Terminate the string (space was ensured above)
|
lineBuf.push_back('\0'); // Terminate the string (space was ensured above)
|
||||||
|
|||||||
Reference in New Issue
Block a user