gbranden pushed a commit to branch master
in repository groff.
commit 58912fa88648af45ea9f3dce817d59d718a43d75
Author: G. Branden Robinson <[email protected]>
AuthorDate: Wed Jun 24 20:07:25 2026 -0500
[libgroff,troff]: Refactor nonreturning functions.
Reallocate fatal error exit responsibilities, and communicate them to
the compiler.
* src/include/error.h: Annotate non-returning
`fatal_with_file_and_line()`, `fatal()`, and `fatal_error_exit()`
functions with `__noreturn__` attribute to ease static analysis.
* src/libs/libgroff/error.cpp (do_error_with_file_and_line): Stop
checking `type` and calling `fatal_error_exit()` if it's `FATAL`.
(fatal, fatal_with_file_and_line): Call `fatal_error_exit()` from here
instead.
* src/roff/troff/div.h: Annotate non-returning
`write_any_trailer_and_exit()` function declaration with
`__noreturn__` attribute to ease static analysis.
* src/roff/troff/input.cpp (do_error): Stop checking `type` and calling
`write_any_trailer_and_exit()` if it's `FATAL`.
(fatal): Call `write_any_trailer_and_exit()` from here instead.
---
ChangeLog | 21 +++++++++++++++++++++
src/include/error.h | 8 +++++---
src/libs/libgroff/error.cpp | 4 ++--
src/roff/troff/div.h | 3 ++-
src/roff/troff/input.cpp | 3 +--
5 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b9795969f..229ab8564 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2026-06-24 G. Branden Robinson <[email protected]>
+
+ [libgroff,troff]: Reallocate fatal error exit responsibilities,
+ and communicate them to the compiler.
+
+ * src/include/error.h: Annotate non-returning
+ `fatal_with_file_and_line()`, `fatal()`, and
+ `fatal_error_exit()` functions with `__noreturn__` attribute to
+ ease static analysis.
+ * src/libs/libgroff/error.cpp (do_error_with_file_and_line):
+ Stop checking `type` and calling `fatal_error_exit()` if it's
+ `FATAL`.
+ (fatal, fatal_with_file_and_line): Call `fatal_error_exit()`
+ from here instead.
+ * src/roff/troff/div.h: Annotate non-returning
+ `write_any_trailer_and_exit()` function declaration with
+ `__noreturn__` attribute to ease static analysis.
+ * src/roff/troff/input.cpp (do_error): Stop checking `type` and
+ calling `write_any_trailer_and_exit()` if it's `FATAL`.
+ (fatal): Call `write_any_trailer_and_exit()` from here instead.
+
2026-06-24 G. Branden Robinson <[email protected]>
* src/libs/libgroff/json_encode.cpp (json_encode_char):
diff --git a/src/include/error.h b/src/include/error.h
index db6c1eb95..ac510b00c 100644
--- a/src/include/error.h
+++ b/src/include/error.h
@@ -21,7 +21,8 @@ along with this program. If not, see
<http://www.gnu.org/licenses/>. */
void fatal_with_file_and_line(const char *, int, const char *,
const errarg & = empty_errarg,
const errarg & = empty_errarg,
- const errarg & = empty_errarg);
+ const errarg & = empty_errarg)
+ __attribute__((__noreturn__));
void error_with_file_and_line(const char *, int, const char *,
const errarg & = empty_errarg,
@@ -41,7 +42,8 @@ void debug_with_file_and_line(const char *, int, const char *,
void fatal(const char *,
const errarg & = empty_errarg,
const errarg & = empty_errarg,
- const errarg & = empty_errarg);
+ const errarg & = empty_errarg)
+ __attribute__((__noreturn__));
void error(const char *,
const errarg & = empty_errarg,
@@ -59,7 +61,7 @@ void debug(const char *,
const errarg & = empty_errarg);
// libgroff/fatal.cpp
-void fatal_error_exit();
+void fatal_error_exit() __attribute__((__noreturn__));
extern "C" const char *program_name;
extern int current_lineno;
diff --git a/src/libs/libgroff/error.cpp b/src/libs/libgroff/error.cpp
index 51ba399a0..63f2badb7 100644
--- a/src/libs/libgroff/error.cpp
+++ b/src/libs/libgroff/error.cpp
@@ -81,8 +81,6 @@ static void do_error_with_file_and_line(const char *filename,
errprint(format, arg1, arg2, arg3);
fputc('\n', stderr);
fflush(stderr);
- if (type == FATAL)
- fatal_error_exit();
}
static void do_error(error_type type,
@@ -127,6 +125,7 @@ void fatal(const char *format,
const errarg &arg3)
{
do_error(FATAL, format, arg1, arg2, arg3);
+ fatal_error_exit();
}
// Use the functions below when it's more costly to save and restore the
@@ -178,6 +177,7 @@ void fatal_with_file_and_line(const char *filename,
{
do_error_with_file_and_line(filename, 0 /* nullptr */, lineno,
FATAL, format, arg1, arg2, arg3);
+ fatal_error_exit();
}
// Local Variables:
diff --git a/src/roff/troff/div.h b/src/roff/troff/div.h
index bbc8c371a..7794c9ead 100644
--- a/src/roff/troff/div.h
+++ b/src/roff/troff/div.h
@@ -176,7 +176,8 @@ void continue_page_eject();
void handle_first_page_transition();
void blank_line();
-extern void write_any_trailer_and_exit(int /* exit_code */);
+extern void write_any_trailer_and_exit(int /* exit_code */)
+ __attribute__((__noreturn__));
// Local Variables:
// fill-column: 72
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index babf1fb4a..fe6bb7918 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -10944,8 +10944,6 @@ static void do_error(error_type type,
}
fputc('\n', stderr);
fflush(stderr);
- if (FATAL == type)
- write_any_trailer_and_exit(EXIT_FAILURE);
}
// This function should have no callers in production builds.
@@ -10991,6 +10989,7 @@ void fatal(const char *format,
const errarg &arg3)
{
do_error(FATAL, WARN_DUMMY, format, arg1, arg2, arg3);
+ write_any_trailer_and_exit(EXIT_FAILURE);
}
void fatal_with_file_and_line(const char *filename, int lineno,
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit