https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89055

David Malcolm <dmalcolm at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dmalcolm at gcc dot gnu.org

--- Comment #1 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
The location ("loc") for the diagnostic is coming from here in
compute_array_index_type_loc:

9644      location_t loc = cp_expr_loc_or_loc (size, name ? name_loc :
input_location);

For the 2nd example:

(gdb) p /x loc
$4 = 0x80000001

(gdb) p /x line_table->location_adhoc_data_map.data[1]
$7 = {locus = 0x285e0, src_range = {m_start = 0x7fffffff, m_finish = 0x28640},
data = 0x0}

i.e. we have regular locations for the caret and finish, but a macro location
for the "start":
(gdb) call inform (line_table->location_adhoc_data_map.data[1].locus, "caret")
t.C:2:21: note: caret
    2 | char b[__SIZE_MAX__ << 1];
      |                     ^
(gdb) call inform
(line_table->location_adhoc_data_map.data[1].src_range.m_start, "start")
t.C:2:8: note: start
    2 | char b[__SIZE_MAX__ << 1];
      |        ^~~~~~~~~~~~
(gdb) call inform
(line_table->location_adhoc_data_map.data[1].src_range.m_finish, "finish")
t.C:2:24: note: finish
    2 | char b[__SIZE_MAX__ << 1];
      |                        ^

When printing "loc", diagnostic-show-locus.c's layout::maybe_add_location_range
generates a sane layout_range:

(gdb) p ri
$15 = {m_start = {m_line = 2, m_column = 8}, m_finish = {m_line = 2, m_column =
24}, 
  m_range_display_kind = SHOW_RANGE_WITH_CARET, m_caret = {m_line = 2, m_column
= 21}, m_original_idx = 0, m_label = 0x0}

but then sanitizes it to just the caret location here:

973       if (start.line > finish.line
974           || !compatible_locations_p (src_range.m_start, m_primary_loc)
975           || !compatible_locations_p (src_range.m_finish, m_primary_loc))
976         {
977           /* Is this the primary location?  */
978           if (m_layout_ranges.length () == 0)
979             {
980               /* We want to print the caret for the primary location, but
981                  we must sanitize away m_start and m_finish.  */
982               ri.m_start = ri.m_caret;
983               ri.m_finish = ri.m_caret;
984             }

due to:
  compatible_locations_p (src_range.m_start, m_primary_loc)
returning false.

As noted in compatible_locations_p, it may be "too strong a condition" (but I'm
loathe to weaken that sanitization in stage 4; it exists due to e.g. PR c/68473
and PR c++/70105).

If I hack out that sanitization, the 2nd is printed, sanely, as:

t.C:2:21: error: size of array ‘b’ is negative
    2 | char b[__SIZE_MAX__ << 1];
      |        ~~~~~~~~~~~~~^~~~

(It's also not clear to me that it's a good idea to be building a compound
location containing macro locations in the first place)

Reply via email to