diff --git a/include/attributes.h b/include/attributes.h new file mode 100644 index 0000000000..13fbe70f42 --- /dev/null +++ b/include/attributes.h @@ -0,0 +1,12 @@ +#ifndef ATTRIBUTES_H +#define ATTRIBUTES_H + +#ifndef __GNUC__ +#define __attribute__(x) +#endif + +#define UNUSED __attribute__((unused)) +#define FALLTHROUGH __attribute__((fallthrough)) +#define NORETURN __attribute__((noreturn)) + +#endif diff --git a/include/fault.h b/include/fault.h index 511d3516fe..c5837f99a3 100644 --- a/include/fault.h +++ b/include/fault.h @@ -42,8 +42,8 @@ void Fault_Init(void); // Fatal Errors -void Fault_AddHungupAndCrashImpl(const char* exp1, const char* exp2); -void Fault_AddHungupAndCrash(const char* file, s32 line); +NORETURN void Fault_AddHungupAndCrashImpl(const char* exp1, const char* exp2); +NORETURN void Fault_AddHungupAndCrash(const char* file, s32 line); // Client Registration diff --git a/include/functions.h b/include/functions.h index 8f83176af1..8430208a24 100644 --- a/include/functions.h +++ b/include/functions.h @@ -30,13 +30,13 @@ void Locale_ResetRegion(void); u32 func_80001F48(void); u32 func_80001F8C(void); u32 Locale_IsRegionNative(void); -void __assert(const char* exp, const char* file, s32 line); +NORETURN void __assert(const char* exp, const char* file, s32 line); void isPrintfInit(void); void osSyncPrintfUnused(const char* fmt, ...); void osSyncPrintf(const char* fmt, ...); void rmonPrintf(const char* fmt, ...); void* is_proutSyncPrintf(void* arg, const char* str, u32 count); -void func_80002384(const char* exp, const char* file, u32 line); +NORETURN void func_80002384(const char* exp, const char* file, u32 line); OSPiHandle* osDriveRomInit(void); void Mio0_Decompress(Yaz0Header* hdr, u8* dst); void StackCheck_Init(StackEntry* entry, void* stackBottom, void* stackTop, u32 initValue, s32 minSpace, @@ -1476,7 +1476,7 @@ u64* SysUcode_GetUCodeBoot(void); size_t SysUcode_GetUCodeBootSize(void); u64* SysUcode_GetUCode(void); u64* SysUcode_GetUCodeData(void); -void func_800D31A0(void); +NORETURN void func_800D31A0(void); void func_800D31F0(void); void func_800D3210(void); void DebugArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action); diff --git a/include/macros.h b/include/macros.h index 89a5d29492..f25069118b 100644 --- a/include/macros.h +++ b/include/macros.h @@ -1,19 +1,12 @@ #ifndef MACROS_H #define MACROS_H -#ifndef __GNUC__ -#define __attribute__(x) -#endif - #ifndef AVOID_UB #define BAD_RETURN(type) type #else #define BAD_RETURN(type) void #endif -#define UNUSED __attribute__((unused)) -#define FALLTHROUGH __attribute__((fallthrough)) - #define ARRAY_COUNT(arr) (s32)(sizeof(arr) / sizeof(arr[0])) #define ARRAY_COUNTU(arr) (u32)(sizeof(arr) / sizeof(arr[0])) diff --git a/include/z64.h b/include/z64.h index 6aed863d74..d0032b6ea3 100644 --- a/include/z64.h +++ b/include/z64.h @@ -3,6 +3,7 @@ #include "ultra64.h" #include "ultra64/gs2dex.h" +#include "attributes.h" #include "z64save.h" #include "z64light.h" #include "z64bgcheck.h" diff --git a/src/boot/assert.c b/src/boot/assert.c index b7895dddda..438432d423 100644 --- a/src/boot/assert.c +++ b/src/boot/assert.c @@ -1,6 +1,6 @@ #include "global.h" -void __assert(const char* exp, const char* file, s32 line) { +NORETURN void __assert(const char* exp, const char* file, s32 line) { char msg[256]; osSyncPrintf("Assertion failed: %s, file %s, line %d, thread %d\n", exp, file, line, osGetThreadId(NULL)); diff --git a/src/boot/is_debug.c b/src/boot/is_debug.c index c064c43a30..5e501f3af7 100644 --- a/src/boot/is_debug.c +++ b/src/boot/is_debug.c @@ -86,7 +86,7 @@ void* is_proutSyncPrintf(void* arg, const char* str, u32 count) { return (void*)1; } -void func_80002384(const char* exp, const char* file, u32 line) { +NORETURN void func_80002384(const char* exp, const char* file, u32 line) { osSyncPrintf("File:%s Line:%d %s \n", file, line, exp); while (true) { ; diff --git a/src/boot/z_std_dma.c b/src/boot/z_std_dma.c index 3b6320b85a..e68b03806a 100644 --- a/src/boot/z_std_dma.c +++ b/src/boot/z_std_dma.c @@ -231,7 +231,7 @@ void DmaMgr_DmaFromDriveRom(void* ram, uintptr_t rom, size_t size) { * * This function does not return. */ -void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorName, const char* errorDesc) { +NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorName, const char* errorDesc) { uintptr_t vrom = req->vromAddr; void* ram = req->dramAddr; size_t size = req->size; diff --git a/src/code/code_800D31A0.c b/src/code/code_800D31A0.c index 6bfa18d97c..a6540c429b 100644 --- a/src/code/code_800D31A0.c +++ b/src/code/code_800D31A0.c @@ -3,7 +3,7 @@ u32 gIsCtrlr2Valid = false; -void func_800D31A0(void) { +NORETURN void func_800D31A0(void) { osSyncPrintf(VT_FGCOL(RED) "\n**** Freeze!! ****\n" VT_RST); while (true) { Sleep_Msec(1000); diff --git a/src/code/fault.c b/src/code/fault.c index 97aeaa75dc..593613f50f 100644 --- a/src/code/fault.c +++ b/src/code/fault.c @@ -1304,19 +1304,25 @@ void Fault_HungupFaultClient(const char* exp1, const char* exp2) { * error occurs. The parameters specify two messages detailing the error, one * or both may be NULL. */ -void Fault_AddHungupAndCrashImpl(const char* exp1, const char* exp2) { +NORETURN void Fault_AddHungupAndCrashImpl(const char* exp1, const char* exp2) { FaultClient client; s32 pad; Fault_AddClient(&client, Fault_HungupFaultClient, (void*)exp1, (void*)exp2); *(u32*)0x11111111 = 0; // trigger an exception via unaligned memory access + + // Since the above line triggers an exception and transfers execution to the fault handler + // this function does not return and the rest of the function is unreachable. +#ifdef __GNUC__ + __builtin_unreachable(); +#endif } /** * Like `Fault_AddHungupAndCrashImpl`, however provides a fixed message containing * filename and line number */ -void Fault_AddHungupAndCrash(const char* file, s32 line) { +NORETURN void Fault_AddHungupAndCrash(const char* file, s32 line) { char msg[256]; sprintf(msg, "HungUp %s:%d", file, line);