xref: /netbsd-src/external/gpl3/gcc/dist/libphobos/libdruntime/core/internal/abort.d (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1 module core.internal.abort;
2 
3 /*
4  * Use instead of assert(0, msg), since this does not print a message for -release compiled
5  * code, and druntime is -release compiled.
6  */
7 void abort(scope string msg, scope string filename = __FILE__, size_t line = __LINE__) @nogc nothrow @safe
8 {
9     import core.stdc.stdlib: c_abort = abort;
10     // use available OS system calls to print the message to stderr
version(Posix)11     version (Posix)
12     {
13         import core.sys.posix.unistd: write;
14         static void writeStr(scope const(char)[][] m...) @nogc nothrow @trusted
15         {
16             foreach (s; m)
17                 write(2, s.ptr, s.length);
18         }
19     }
version(Windows)20     else version (Windows)
21     {
22         import core.sys.windows.winbase : GetStdHandle, STD_ERROR_HANDLE, WriteFile, INVALID_HANDLE_VALUE;
23         auto h = (() @trusted => GetStdHandle(STD_ERROR_HANDLE))();
24         if (h == INVALID_HANDLE_VALUE)
25         {
26             // attempt best we can to print the message
27 
28             /* Note that msg is scope.
29              * assert() calls _d_assert_msg() calls onAssertErrorMsg() calls _assertHandler() but
30              * msg parameter isn't scope and can escape.
31              * Give up and use our own immutable message instead.
32              */
33             assert(0, "Cannot get stderr handle for message");
34         }
35         void writeStr(scope const(char)[][] m...) @nogc nothrow @trusted
36         {
37             foreach (s; m)
38             {
39                 assert(s.length <= uint.max);
40                 WriteFile(h, s.ptr, cast(uint)s.length, null, null);
41             }
42         }
43     }
44     else
45         static assert(0, "Unsupported OS");
46 
47     import core.internal.string;
48     UnsignedStringBuf strbuff = void;
49 
50     // write an appropriate message, then abort the program
51     writeStr("Aborting from ", filename, "(", line.unsignedToTempString(strbuff), ") ", msg);
52     c_abort();
53 }
54