Added warning for static functions used but never defined
authorRobert Pengelly <robertapengelly@hotmail.com>
Mon, 24 Aug 2026 12:37:30 +0000 (13:37 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Mon, 24 Aug 2026 12:37:30 +0000 (13:37 +0100)
amd64.c
cc.h
i386.c
parse.c
parse.h

diff --git a/amd64.c b/amd64.c
index 4308f833be653fd36d83a609b916f346e185f6b2..d05ba321bf955db587fa0446ae5e6f481121b42c 100644 (file)
--- a/amd64.c
+++ b/amd64.c
@@ -40605,6 +40605,8 @@ static void parse_external_after_type (void) {
                 
                 if (find_global_symbol (name) >= 0) {
                 
+                    global_symbols[find_global_symbol (name)].is_static = (declaration_storage == STORAGE_STATIC);
+                    
                     set_global_symbol_size (name, declarator_is_pointer ? DATA_PTR : (parsed_type_is_void ? DATA_VOID : parsed_type_size));
                     set_global_symbol_pointer_info (name, declarator_effective_pointer_depth_now (),
                         declarator_effective_pointed_size_now (parsed_type_size, object_fields, object_field_count));
@@ -40772,7 +40774,9 @@ void compile_translation_unit64 (void) {
         masm_flush_data_line ();
     }
     
+    warn_undefined_static_functions (get_filename ());
     warn_unused_static_functions (get_filename ());
+    
     emit_pending_extern_symbols ();
     
     if (vec_dllexports.length || vec_dllaliases.length) {
diff --git a/cc.h b/cc.h
index 3243bb577d936d7615a9e6467ee677b8a0b2302a..9847d3bbeda78694f285c94a0268a47cc4300054 100755 (executable)
--- a/cc.h
+++ b/cc.h
@@ -21,8 +21,9 @@
 #define     WARN_FALLTHROUGH            (1U << 8)
 #define     WARN_OLD_STYLE              (1U << 9)
 #define     WARN_INITIALIZER            (1U << 10)
+#define     WARN_STATIC_UNDEFINED       (1U << 11)
 
-#define     WARN_DEFAULT                (WARN_DUP_DEFINE)
+#define     WARN_DEFAULT                (WARN_DUP_DEFINE | WARN_STATIC_UNDEFINED)
 #define     WARN_ALL                    (WARN_DEFAULT | WARN_NO_RETURN | WARN_SIGNEDNESS | WARN_UNUSED | WARN_FALLTHROUGH | WARN_INITIALIZER)
 #define     WARN_EXTRA                  (WARN_ALL | WARN_CONVERSION | WARN_OLD_STYLE)
 
diff --git a/i386.c b/i386.c
index 3f08288aae2b11c87c8c822bf035e67bef05a590..ff467db071a3f45374c3f4dc56a9ddebeddeca3c 100644 (file)
--- a/i386.c
+++ b/i386.c
@@ -37902,6 +37902,8 @@ static void parse_external_after_type (void) {
                 
                 if (find_global_symbol (name) >= 0) {
                 
+                    global_symbols[find_global_symbol (name)].is_static = (declaration_storage == STORAGE_STATIC);
+                    
                     set_global_symbol_size (name, declarator_is_pointer ? DATA_PTR : (parsed_type_is_void ? DATA_VOID : parsed_type_size));
                     set_global_symbol_pointer_info (name, declarator_effective_pointer_depth_now (),
                         declarator_effective_pointed_size_now (parsed_type_size, object_fields, object_field_count));
@@ -38072,7 +38074,9 @@ void compile_translation_unit32 (void) {
         masm_flush_data_line ();
     }
     
+    warn_undefined_static_functions (get_filename ());
     warn_unused_static_functions (get_filename ());
+    
     emit_pending_extern_symbols ();
     
     if (vec_dllexports.length || vec_dllaliases.length) {
diff --git a/parse.c b/parse.c
index 393b884101036d384baa40bdd51ab99fad2ce567..f86fb9d364b1823190f525490e39d9f558e9e3cb 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -2409,6 +2409,35 @@ void warn_unused_local_symbols (int start, const char *filename) {
 
 }
 
+void warn_undefined_static_functions (const char *filename) {
+
+    int i;
+    
+    if (!state || !(state->warn & WARN_STATIC_UNDEFINED)) {
+        return;
+    }
+    
+    for (i = 0; i < global_symbol_count; i++) {
+    
+        struct global_symbol_entry *sym = &global_symbols[i];
+        
+        if (sym->kind != GLOBAL_SYMBOL_FUNCTION || !sym->is_static || !sym->used || !sym->is_extern) {
+            continue;
+        }
+        
+        if (sym->decl_start && sym->decl_line) {
+        
+            report_line_at (sym->decl_filename ? sym->decl_filename : (filename ? filename : get_filename ()), sym->decl_line, REPORT_WARNING,
+                sym->decl_start, sym->decl_start + sym->decl_caret_offset, "'%s' used but never defined", sym->name);
+        
+        } else {
+            report_at (filename ? filename : get_filename (), get_line_number (), REPORT_WARNING, "'%s' used but never defined", sym->name);
+        }
+    
+    }
+
+}
+
 void warn_unused_static_functions (const char *filename) {
 
     int i;
diff --git a/parse.h b/parse.h
index 541a3a00d6de785d4335d7b84dc33e0112eb6811..16e3d79c543e93524b487c136e474274de358af2 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -221,6 +221,7 @@ struct local_symbol *peek_local_symbol (const char *name);
 void warn_shadow_symbol (const char *name, int scope_start_count, int line, const char *start, const char *caret, int is_parameter);
 void warn_unused_local_symbols (int start, const char *filename);
 void warn_unused_static_functions (const char *filename);
+void warn_undefined_static_functions (const char *filename);
 
 #define     MAX_GLOBAL_SYMBOLS          4096
 int find_global_symbol (const char *name);