diff --git a/rts/sm/GCAux.c b/rts/sm/GCAux.c
index 23ed3f0622f77ea3060d637c1cbbf06ed5bc6851..e8ca0c4002a0dc8aec615e20637d7bfda2972307 100644
--- a/rts/sm/GCAux.c
+++ b/rts/sm/GCAux.c
@@ -114,16 +114,21 @@ isAlive(StgClosure *p)
 void
 revertCAFs( void )
 {
-    StgIndStatic *c;
+    StgIndStatic *c = revertible_caf_list;
 
-    for (c = revertible_caf_list;
-         c != (StgIndStatic *)END_OF_CAF_LIST;
-         c = (StgIndStatic *)c->static_link)
-    {
+    while (c != (StgIndStatic *) END_OF_CAF_LIST) {
         c = (StgIndStatic *)UNTAG_STATIC_LIST_PTR(c);
+        StgIndStatic *next = (StgIndStatic *) c->static_link;
+
         SET_INFO((StgClosure *)c, c->saved_info);
         c->saved_info = NULL;
-        // could, but not necessary: c->static_link = NULL;
+        // We must reset static_link lest the major GC finds that
+        // static_flag==3 and will consequently ignore references
+        // into code that we are trying to unload. This would result
+        // in reachable object code being unloaded prematurely.
+        // See #16842.
+        c->static_link = NULL;
+        c = next;
     }
     revertible_caf_list = (StgIndStatic*)END_OF_CAF_LIST;
 }