This repository has been archived by the owner on Jan 24, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds checks for validating assert, improves assertion behaviour based…
… on code size optimization, adds configuration for assertion macro behaviour
- Loading branch information
Felix "xq" Queißner
committed
Jan 23, 2024
1 parent
0c228a7
commit 843d8bf
Showing
7 changed files
with
153 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,43 @@ | ||
#ifndef _FOUNDATION_LIBC_ASSERT_H_ | ||
#define _FOUNDATION_LIBC_ASSERT_H_ | ||
|
||
#ifndef NDEBUG | ||
#define assert(expr) | ||
#else | ||
extern void __assert(char const * assertion, char const * file, unsigned line) __attribute__((__noreturn__)); | ||
#include "foundation/builtins.h" | ||
|
||
extern FOUNDATION_LIBC_NORETURN void foundation_libc_assert(char const * assertion, char const * file, unsigned line); | ||
|
||
#if FOUNDATION_LIBC_ASSERT == FOUNDATION_LIBC_ASSERT_DEFAULT | ||
|
||
#define assert(expr) \ | ||
do { \ | ||
if ((expr) == 0) { \ | ||
foundation_libc_assert(#expr, __FILE__, __LINE__); \ | ||
} \ | ||
} while (0) | ||
|
||
#elif FOUNDATION_LIBC_ASSERT == FOUNDATION_LIBC_ASSERT_NOFILE | ||
|
||
#define assert(expr) \ | ||
((expr) \ | ||
? void(0) \ | ||
: __assert(#expr, __FILE__, __LINE__)) | ||
#define assert(expr) \ | ||
do { \ | ||
if ((expr) == 0) { \ | ||
foundation_libc_assert(#expr, "", __LINE__); \ | ||
} \ | ||
} while (0) | ||
|
||
#elif FOUNDATION_LIBC_ASSERT == FOUNDATION_LIBC_ASSERT_NOMSG | ||
|
||
#define assert(expr) \ | ||
do { \ | ||
if ((expr) == 0) { \ | ||
foundation_libc_assert("", "", __LINE__); \ | ||
} \ | ||
} while (0) | ||
|
||
#elif FOUNDATION_LIBC_ASSERT == FOUNDATION_LIBC_ASSERT_EXPECTED | ||
|
||
#define assert(expr) FOUNDATION_LIBC_EXPECT(expr) | ||
|
||
#else | ||
#error "bad definition of FOUNDATION_LIBC_ASSERT_DEFAULT!" | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#ifndef _FOUNDATION_LIBC_BUILTINS_H_ | ||
#define _FOUNDATION_LIBC_BUILTINS_H_ | ||
|
||
#include <stddef.h> | ||
|
||
#define FOUNDATION_LIBC_ASSERT_DEFAULT 0 | ||
#define FOUNDATION_LIBC_ASSERT_NOFILE 1 | ||
#define FOUNDATION_LIBC_ASSERT_NOMSG 2 | ||
#define FOUNDATION_LIBC_ASSERT_EXPECTED 3 | ||
|
||
#ifndef FOUNDATION_LIBC_ASSERT | ||
#define FOUNDATION_LIBC_ASSERT FOUNDATION_LIBC_ASSERT_DEFAULT | ||
#endif | ||
|
||
#if defined(__clang__) | ||
|
||
#define FOUNDATION_LIBC_NORETURN __attribute__((__noreturn__)) | ||
#define FOUNDATION_LIBC_EXPECT(expr) (__builtin_expect(!(expr), 0)) | ||
|
||
#elif defined(__GNUC__) || defined(__GNUG__) | ||
|
||
#define FOUNDATION_LIBC_NORETURN __attribute__((__noreturn__)) | ||
#define FOUNDATION_LIBC_EXPECT(expr) (__builtin_expect(!(expr), 0)) | ||
|
||
#elif defined(_MSC_VER) | ||
|
||
#define FOUNDATION_LIBC_NORETURN __declspec(noreturn) | ||
#define FOUNDATION_LIBC_EXPECT(expr) (__assume((expr))) | ||
|
||
#else | ||
|
||
#define FOUNDATION_LIBC_NORETURN | ||
#define FOUNDATION_LIBC_EXPECT(expr) | ||
|
||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,20 @@ | ||
const std = @import("std"); | ||
const builtin = @import("builtin"); | ||
|
||
export fn __assert( | ||
export fn foundation_libc_assert( | ||
assertion: ?[*:0]const u8, | ||
file: ?[*:0]const u8, | ||
line: c_uint, | ||
) noreturn { | ||
var buf: [256]u8 = undefined; | ||
const str = std.fmt.bufPrint(&buf, "assertion failed: '{?s}' in file {?s} line {}", .{ assertion, file, line }) catch { | ||
@panic("assertion failed"); | ||
}; | ||
|
||
@panic(str); | ||
switch (builtin.mode) { | ||
.Debug, .ReleaseSafe => { | ||
var buf: [256]u8 = undefined; | ||
const str = std.fmt.bufPrint(&buf, "assertion failed: '{?s}' in file {?s} line {}", .{ assertion, file, line }) catch { | ||
@panic("assertion failed"); | ||
}; | ||
@panic(str); | ||
}, | ||
.ReleaseSmall => @panic("assertion failed"), | ||
.ReleaseFast => unreachable, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include <assert.h> | ||
|
||
#ifndef FOUNDATION_LIBC_ASSERT | ||
#error "FOUNDATION_LIBC_ASSERT wasn't implicitly or explicitly defined by assert.h" | ||
#endif | ||
|
||
#pragma GCC diagnostic ignored "-Wunused-function" | ||
#pragma GCC diagnostic ignored "-Wmissing-prototypes" | ||
// | ||
|
||
void assert_dynamic(int ok) { | ||
assert(ok); | ||
} | ||
|
||
void assert_ok(void) { | ||
assert(1); | ||
} | ||
|
||
// suppress noreturn diagnostic for missing "noreturn" | ||
#pragma GCC diagnostic ignored "-Wmissing-noreturn" | ||
// | ||
|
||
void assert_bad(void) { | ||
assert(0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters