diff --git a/includes/RtsAPI.h b/includes/RtsAPI.h
index 1444dbc3c587b16ef4768f7cf09b43a0f78e001d..dc151faf071a6a63f07a9d30876ad1803305cf1c 100644
--- a/includes/RtsAPI.h
+++ b/includes/RtsAPI.h
@@ -43,7 +43,11 @@ typedef struct Capability_ Capability;
 extern void startupHaskell         ( int argc, char *argv[], 
 				     void (*init_root)(void) );
 extern void shutdownHaskell        ( void );
-extern void shutdownHaskellAndExit ( int exitCode );
+extern void shutdownHaskellAndExit ( int exitCode )
+#if __GNUC__ >= 3
+    __attribute__((__noreturn__))
+#endif
+    ;
 extern void getProgArgv            ( int *argc, char **argv[] );
 extern void setProgArgv            ( int argc, char *argv[] );
 extern void getFullProgArgv        ( int *argc, char **argv[] );
diff --git a/rts/RtsMain.c b/rts/RtsMain.c
index 0ed6df494c25ceaee07bf7acac76cfb187300901..a822da9749f2ebe29b7d19311ea41fa71dbd54d3 100644
--- a/rts/RtsMain.c
+++ b/rts/RtsMain.c
@@ -38,6 +38,7 @@ static StgClosure *progmain_closure;  /* This will be ZCMain_main_closure */
  * INTERPRETER is set
  */
 #ifndef INTERPRETER /* Hack */
+static void real_main(void) GNUC3_ATTRIBUTE(__noreturn__);
 static void real_main(void)
 {
     int exit_status;
@@ -112,6 +113,5 @@ int hs_main(int argc, char *argv[], StgClosure *main_closure)
 #if defined(mingw32_HOST_OS)
     END_CATCH
 #endif
-    return 0; /* not reached, but keeps gcc -Wall happy */
 }
 # endif /* BATCH_MODE */
diff --git a/rts/RtsMain.h b/rts/RtsMain.h
index 24e58199bbdf0a6a682aea8a2828ef60b176da73..e004480ccee2035cfb618c51fa06094c7ec9a143 100644
--- a/rts/RtsMain.h
+++ b/rts/RtsMain.h
@@ -13,6 +13,7 @@
  * The entry point for Haskell programs that use a Haskell main function
  * -------------------------------------------------------------------------- */
 
-int hs_main(int argc, char *argv[], StgClosure *main_closure);
+int hs_main(int argc, char *argv[], StgClosure *main_closure)
+   GNUC3_ATTRIBUTE(__noreturn__);
 
 #endif /* RTSMAIN_H */
diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c
index c115701d6ccc5a65079df0d356719aaad1a9d772..6e18fba27399ee67769e0e0305b7e4d0f692d7ab 100644
--- a/rts/RtsStartup.c
+++ b/rts/RtsStartup.c
@@ -424,12 +424,14 @@ shutdownHaskell(void)
 void
 shutdownHaskellAndExit(int n)
 {
+    // even if hs_init_count > 1, we still want to shut down the RTS
+    // and exit immediately (see #5402)
+    hs_init_count = 1;
+
     // we're about to exit(), no need to wait for foreign calls to return.
     hs_exit_(rtsFalse);
 
-    if (hs_init_count == 0) {
-	stg_exit(n);
-    }
+    stg_exit(n);
 }
 
 #ifndef mingw32_HOST_OS