https://gcc.gnu.org/g:37a0ec2591c6d984d1527345245005b627124553

commit r16-5312-g37a0ec2591c6d984d1527345245005b627124553
Author: Lewis Hyatt <[email protected]>
Date:   Sat Nov 15 23:10:52 2025 -0500

    diagnostics: Fix -fdump-internal-locations for 64-bit location_t
    
    When adding support for 64-bit location_t in GCC 15, I missed a couple
    changes needed for the internal debugging tool -fdump-internal-locations to
    work properly. This would previously ICE on a location_t large enough to
    overflow a signed 32-bit int.
    
    gcc/ChangeLog:
    
            * diagnostics/context.cc (num_digits): Change argument type from
            `int' to `uint64_t'.
            (test_num_digits): Add test for 64-bit argument.
            * diagnostic.h (num_digits): Adjust prototype.
            * input.cc (write_digit): Accept argument in range 0-9 instead of
            an arbitrary int.
            (write_digit_row): Adjust to change in write_digit().
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/plugin/location-overflow-test-3.c: New test.
            * gcc.dg/plugin/plugin.exp: Add the new test.

Diff:
---
 gcc/diagnostic.h                                       |  2 +-
 gcc/diagnostics/context.cc                             |  4 ++--
 gcc/input.cc                                           |  4 ++--
 gcc/testsuite/gcc.dg/plugin/location-overflow-test-3.c | 10 ++++++++++
 gcc/testsuite/gcc.dg/plugin/plugin.exp                 |  1 +
 5 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 7d730461e241..4b89643d113d 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -275,7 +275,7 @@ option_unspecified_p (diagnostics::option_id opt_id)
 namespace diagnostics {
 
 /* Compute the number of digits in the decimal representation of an integer.  
*/
-extern int num_digits (int);
+extern int num_digits (uint64_t);
 
 } // namespace diagnostics
 
diff --git a/gcc/diagnostics/context.cc b/gcc/diagnostics/context.cc
index dd6bbdb29cd7..2543a6031ecb 100644
--- a/gcc/diagnostics/context.cc
+++ b/gcc/diagnostics/context.cc
@@ -1592,11 +1592,10 @@ context::report_global_digraph (const 
lazily_created<digraphs::digraph> &ldg)
 /* Get the number of digits in the decimal representation of VALUE.  */
 
 int
-num_digits (int value)
+num_digits (uint64_t value)
 {
   /* Perhaps simpler to use log10 for this, but doing it this way avoids
      using floating point.  */
-  gcc_assert (value >= 0);
 
   if (value == 0)
     return 1;
@@ -2299,6 +2298,7 @@ test_num_digits ()
   ASSERT_EQ (7, num_digits (9999999));
   ASSERT_EQ (8, num_digits (10000000));
   ASSERT_EQ (8, num_digits (99999999));
+  ASSERT_EQ (20, num_digits (uint64_t (-1)));
 }
 
 /* Run all of the selftests within this file.
diff --git a/gcc/input.cc b/gcc/input.cc
index aad983947114..665dbe3d6053 100644
--- a/gcc/input.cc
+++ b/gcc/input.cc
@@ -464,7 +464,7 @@ get_end_location (class line_maps *set, line_map_uint_t idx)
 static void
 write_digit (FILE *stream, int digit)
 {
-  fputc ('0' + (digit % 10), stream);
+  fputc ('0' + digit, stream);
 }
 
 /* Helper function for dump_location_info.
@@ -481,7 +481,7 @@ write_digit_row (FILE *stream, int indent,
   for (int column = 1; column < max_col; column++)
     {
       location_t column_loc = loc + (location_t (column) << map->m_range_bits);
-      write_digit (stream, column_loc / divisor);
+      write_digit (stream, (column_loc / divisor) % 10);
     }
   fprintf (stream, "\n");
 }
diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-3.c 
b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-3.c
new file mode 100644
index 000000000000..2acf1c3a1c8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-3.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-fplugin-arg-location_overflow_plugin-value=1024 
-fdump-internal-locations" } */
+
+/* The plugin arranges for location_t values to exceed 32 bits; verify the
+   internal dump routines don't crash. The exact output depends on the system
+   and on absolute path names, and this output is only meant for internal
+   purposes, so don't demand an exact form of the output.  */
+
+/* { dg-allow-blank-lines-in-output 1 } */
+/* { dg-prune-output ".*" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp 
b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 38991e8e6191..83ef1b2dd939 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -145,6 +145,7 @@ set plugin_test_list [list \
     { location_overflow_plugin.cc \
          location-overflow-test-1.c \
          location-overflow-test-2.c \
+         location-overflow-test-3.c \
          location-overflow-test-pr83173.c \
          location-overflow-test-pr116047.c \
          location-overflow-test-pr120061.c } \

Reply via email to