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

Reply via email to