Skip to content

Commit f279ab5

Browse files
abrachetmemfrob
authored andcommitted
[libc] Add initial assert definition
Summary: This patch adds a temporary `__assert_fail` and `assert` definition to make it available to internal llvm libc code. `__assert_fail` writes to fd 2 directly instead of `stderr`, using SYS_write. I have not put it in its own linux directory because this is temporary and it should be using stdio's api in the future. It does not currently print out the line number (although we could do that by stringifying `__LINE__` if reviewers wish). Reviewers: sivachandra, gchatelet, PaulkaToast Reviewed By: sivachandra Subscribers: mgorny, MaskRay, tschuett, libc-commits Differential Revision: https://reviews.llvm.org/D75420
1 parent 0ae5680 commit f279ab5

File tree

12 files changed

+204
-0
lines changed

12 files changed

+204
-0
lines changed

libc/config/linux/api.td

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,35 @@ def OffT : TypeDecl<"off_t"> {
1818
}];
1919
}
2020

21+
def AssertMacro : MacroDef<"assert"> {
22+
let Defn = [{
23+
#undef assert
24+
25+
#ifdef NDEBUG
26+
#define assert(e) (void)0
27+
#else
28+
29+
#ifdef __cplusplus
30+
extern "C"
31+
#endif
32+
_Noreturn void __assert_fail(const char *, const char *, unsigned, const char *);
33+
34+
#define assert(e) \
35+
((e) ? (void)0 : __assert_fail(#e, __FILE__, __LINE__, __PRETTY_FUNCTION__))
36+
37+
#endif
38+
}];
39+
}
40+
41+
def StaticAssertMacro : MacroDef<"static_assert"> {
42+
let Defn = [{
43+
#ifndef __cplusplus
44+
#undef static_assert
45+
#define static_assert _Static_assert
46+
#endif
47+
}];
48+
}
49+
2150
def NullMacro : MacroDef<"NULL"> {
2251
let Defn = [{
2352
#define __need_NULL
@@ -35,6 +64,13 @@ def ErrnoMacro : MacroDef<"errno"> {
3564
}];
3665
}
3766

67+
def AssertAPI : PublicAPI<"assert.h"> {
68+
let Macros = [
69+
AssertMacro,
70+
StaticAssertMacro,
71+
];
72+
}
73+
3874
def MathAPI : PublicAPI<"math.h"> {
3975
let Functions = [
4076
"acos",

libc/include/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ add_header(
2727
llvm_libc_common_h
2828
)
2929

30+
add_gen_header(
31+
assert_h
32+
DEF_FILE assert.h.def
33+
GEN_HDR assert.h
34+
DEPENDS
35+
llvm_libc_common_h
36+
)
37+
3038
add_gen_header(
3139
string_h
3240
DEF_FILE string.h.def

libc/include/assert.h.def

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//===---------------- C standard library header assert.h ------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include <__llvm-libc-common.h>
10+
11+
// This file may be usefully included multiple times to change assert()'s
12+
// definition based on NDEBUG.
13+
14+
%%public_api()

libc/lib/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
add_entrypoint_library(
33
llvmlibc
44
DEPENDS
5+
# assert.h entrypoints
6+
__assert_fail
7+
58
# errno.h entrypoints
69
__errno_location
710

libc/spec/stdc.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ def StdC : StandardSpec<"stdc"> {
1616

1717
PtrType IntPtr = PtrType<IntType>;
1818

19+
HeaderSpec Assert = HeaderSpec<
20+
"assert.h",
21+
[
22+
Macro<"static_assert">,
23+
Macro<"assert">,
24+
],
25+
[], // Types
26+
[], // Enumerations
27+
[]
28+
>;
29+
1930
HeaderSpec String = HeaderSpec<
2031
"string.h",
2132
[
@@ -285,6 +296,7 @@ def StdC : StandardSpec<"stdc"> {
285296
>;
286297

287298
let Headers = [
299+
Assert,
288300
Errno,
289301
Math,
290302
String,

libc/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
add_subdirectory(assert)
12
add_subdirectory(errno)
23
add_subdirectory(math)
34
add_subdirectory(signal)

libc/src/assert/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
add_entrypoint_object(
2+
__assert_fail
3+
SRCS
4+
__assert_fail.cpp
5+
HDRS
6+
assert.h
7+
DEPENDS
8+
abort
9+
# These two dependencies are temporary and should be replaced by fprintf
10+
# later.
11+
sys_syscall_h
12+
linux_syscall_h
13+
)

libc/src/assert/__assert_fail.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===----------------- Implementation of __assert_fail --------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/assert/assert.h"
10+
#include "src/stdlib/abort.h"
11+
12+
// These includes are temporary.
13+
#include "config/linux/syscall.h" // For internal syscall function.
14+
#include "include/sys/syscall.h" // For syscall numbers.
15+
16+
namespace __llvm_libc {
17+
18+
// This is just a temporary solution to make assert available to internal
19+
// llvm libc code. In the future writeToStderr will not exist and __assert_fail
20+
// will call fprintf(stderr, ...).
21+
static void writeToStderr(const char *s) {
22+
size_t length = 0;
23+
for (const char *curr = s; *curr; ++curr, ++length);
24+
__llvm_libc::syscall(SYS_write, 2, s, length);
25+
}
26+
27+
void LLVM_LIBC_ENTRYPOINT(__assert_fail)(const char *assertion, const char *file,
28+
unsigned line, const char *function) {
29+
writeToStderr(file);
30+
writeToStderr(": Assertion failed: '");
31+
writeToStderr(assertion);
32+
writeToStderr("' in function: '");
33+
writeToStderr(function);
34+
writeToStderr("'\n");
35+
__llvm_libc::abort();
36+
}
37+
38+
} // namespace __llvm_libc

libc/src/assert/assert.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===-------------------- Internal header for assert ----------*- C++ -*---===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_ASSERT_ASSERT_H
10+
#define LLVM_LIBC_SRC_ASSERT_ASSERT_H
11+
12+
#include <stddef.h>
13+
14+
namespace __llvm_libc {
15+
16+
[[noreturn]] void __assert_fail(const char *assertion, const char *file, unsigned line,
17+
const char *function);
18+
19+
} // namespace __llvm_libc
20+
21+
#endif // LLVM_LIBC_SRC_ASSERT_ASSERT_H
22+
23+
#undef assert
24+
25+
#ifdef NDEBUG
26+
#define assert(e) (void)0
27+
#else
28+
#define assert(e) \
29+
((e) ? (void)0 : \
30+
__llvm_libc::__assert_fail(#e, __FILE__, __LINE__, __PRETTY_FUNCTION__))
31+
#endif

libc/test/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
add_subdirectory(assert)
12
add_subdirectory(errno)
23
add_subdirectory(signal)
34
add_subdirectory(stdlib)

0 commit comments

Comments
 (0)