Added shadow warnings
authorRobert Pengelly <robertapengelly@hotmail.com>
Sun, 23 Aug 2026 11:22:17 +0000 (12:22 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Sun, 23 Aug 2026 11:22:17 +0000 (12:22 +0100)
amd64.c
cc.h
i386.c
lib.c
parse.c
parse.h

diff --git a/amd64.c b/amd64.c
index 26b4360d0c6b51e4ee791bcfc0d02502c9764544..a4557312a7d79892350cc74d9635993d1233c2dd 100644 (file)
--- a/amd64.c
+++ b/amd64.c
@@ -5835,6 +5835,7 @@ static long add_local_symbol (const char *name, int size, int align, int is_unsi
     
     }
     
+    warn_shadow_symbol (name, scope_start_count, line, start, caret, 0);
     new_size = align_up_long (current_local_stack_size + size, align);
     
     /*
@@ -5915,6 +5916,8 @@ static void add_static_local_symbol (const char *name, const char *label, int si
     
     }
     
+    warn_shadow_symbol (name, scope_start_count, line, start, caret, 0);
+    
     local_symbols[local_symbol_count].name = xstrdup (name);
     local_symbols[local_symbol_count].static_label = xstrdup (label);
     local_symbols[local_symbol_count].size = size;
@@ -6203,6 +6206,9 @@ static void install_pending_params_as_locals (void) {
             report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate parameter '%s'", pending_params[i].name);
         }
         
+        warn_shadow_symbol (pending_params[i].name, 0, pending_params[i].decl_line,
+            pending_params[i].decl_start, pending_params[i].decl_start ? pending_params[i].decl_start + pending_params[i].decl_caret_offset : 0, 1);
+        
         local_symbols[local_symbol_count].name = xstrdup (pending_params[i].name);
         local_symbols[local_symbol_count].size = pending_params[i].size;
         local_symbols[local_symbol_count].align = pending_params[i].align;
diff --git a/cc.h b/cc.h
index 997bbdacc9ecf7e169b92839366ef992ca2095a2..b30e43df5aec7a77fed0735b28e952068440b161 100755 (executable)
--- a/cc.h
+++ b/cc.h
@@ -24,7 +24,7 @@
 
 #define     WARN_DEFAULT                (WARN_DUP_DEFINE | WARN_UNREACHABLE)
 #define     WARN_ALL                    (WARN_DEFAULT | WARN_NO_RETURN | WARN_SIGNEDNESS | WARN_UNUSED | WARN_FALLTHROUGH | WARN_INITIALIZER)
-#define     WARN_EXTRA                  (WARN_ALL | WARN_CONVERSION | WARN_SHADOW | WARN_OLD_STYLE)
+#define     WARN_EXTRA                  (WARN_ALL | WARN_CONVERSION | WARN_OLD_STYLE)
 
 struct cc_state {
     
diff --git a/i386.c b/i386.c
index ad89ec59fb5e33a099ff4b64fea608ba33f0c509..096d5e6c7919ec1b18e3c08185623c79143d72ff 100644 (file)
--- a/i386.c
+++ b/i386.c
@@ -5515,6 +5515,7 @@ static long add_local_symbol (const char *name, int size, int align, int is_unsi
     
     }
     
+    warn_shadow_symbol (name, scope_start_count, line, start, caret, 0);
     new_size = align_up_long (current_local_stack_size + size, align);
     
     /*
@@ -5595,6 +5596,8 @@ static void add_static_local_symbol (const char *name, const char *label, int si
     
     }
     
+    warn_shadow_symbol (name, scope_start_count, line, start, caret, 0);
+    
     local_symbols[local_symbol_count].name = xstrdup (name);
     local_symbols[local_symbol_count].static_label = xstrdup (label);
     local_symbols[local_symbol_count].size = size;
@@ -5883,6 +5886,9 @@ static void install_pending_params_as_locals (void) {
             report_line_at (get_filename (), get_line_number (), REPORT_ERROR, tok.report_start, tok.report_caret, "duplicate parameter '%s'", pending_params[i].name);
         }
         
+        warn_shadow_symbol (pending_params[i].name, 0, pending_params[i].decl_line,
+            pending_params[i].decl_start, pending_params[i].decl_start ? pending_params[i].decl_start + pending_params[i].decl_caret_offset : 0, 1);
+        
         local_symbols[local_symbol_count].name = xstrdup (pending_params[i].name);
         local_symbols[local_symbol_count].size = pending_params[i].size;
         local_symbols[local_symbol_count].align = pending_params[i].align;
diff --git a/lib.c b/lib.c
index 1add87cf775ba88047d9804ae7010b1c4230f893..7e79dafd1a0793ab3a29bf2202b8a5976f150368 100755 (executable)
--- a/lib.c
+++ b/lib.c
@@ -572,6 +572,13 @@ void parse_args (int argc, char **argv, int optind) {
                 
                 }
                 
+                if (strcmp (optarg, "shadow") == 0) {
+                
+                    state->warn |= WARN_SHADOW;
+                    break;
+                
+                }
+                
                 report_at (program_name, 0, REPORT_ERROR, "unrecognised -W argument");
                 exit (EXIT_FAILURE);
             
diff --git a/parse.c b/parse.c
index 2ad1400ded4f115f4cce023fc54c053f5a1847b2..d7775ad0c85dc18144ba942aca197abd2d47719c 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -2305,6 +2305,57 @@ struct local_symbol *find_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) {
+
+    const char *what = 0;
+    int i;
+    
+    if (!state || !(state->warn & WARN_SHADOW) || !name) {
+        return;
+    }
+    
+    if (!is_parameter) {
+    
+        if (scope_start_count < 0) {
+            scope_start_count = 0;
+        }
+        
+        if (scope_start_count > local_symbol_count) {
+            scope_start_count = local_symbol_count;
+        }
+        
+        for (i = scope_start_count - 1; i >= 0; i--) {
+        
+            if (local_symbols[i].name && strcmp (local_symbols[i].name, name) == 0) {
+            
+                what = local_symbols[i].offset > 0 ? "parameter" : "local variable";
+                break;
+            
+            }
+        
+        }
+    
+    }
+    
+    if (!what && find_global_symbol (name) >= 0) {
+        what = "global declaration";
+    }
+    
+    if (!what) {
+        return;
+    }
+    
+    if (start && caret) {
+    
+        report_line_at (get_filename (), line, REPORT_WARNING, start, caret,
+            "declaration of '%s' shadows a %s", name, what);
+    
+    } else {
+        report_at (get_filename (), line, REPORT_WARNING, "declaration of '%s' shadows a %s", name, what);
+    }
+
+}
+
 void warn_unused_local_symbols (int start, const char *filename) {
 
     int i;
diff --git a/parse.h b/parse.h
index 8b52fd891223c9410f750f87f91d0b4937af47f2..31c5a295e6c948957bb4953af3a75eca049a3e6d 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -215,6 +215,7 @@ extern int local_symbol_count;
 struct local_symbol *find_local_symbol (const char *name);
 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);