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

--- Comment #2 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
Thanks.

It's attempting to dereference a NULL file when erroneously attempting to
serialize UNKNOWN_LOCATION for the finish_loc of a location range.

Notice how:
  deprecated-copy-crash.cc:43:5: warning: implicitly-declared ‘constexpr G&
G::operator=(const G&)’ is deprecated [-Wdeprecated-copy]
   43 |   a = r();

doesn't have any caret or underlines.


The warning is emitted here at gcc/cp/decl2.c:

5349              warned = warning (opt, "implicitly-declared %qD is
deprecated",
5350                                decl);

(gdb) p /x input_location
$10 = 0x80000003
(gdb) p line_table->location_adhoc_data_map.data[3]
$13 = {locus = 332768, src_range = {m_start = 332704, m_finish = 0}, data =
0x0}

/tmp/pr90462.C: In instantiation of ‘void h< <template-parameter-1-1>,
<template-parameter-1-2> >::o(const i*, const i*, unsigned int) [with i = char;
<template-parameter-1-2> = int]’:
/tmp/pr90462.C:22:5:   required from ‘void b< <template-parameter-1-1>
>::assign() [with i = char]’
/tmp/pr90462.C:28:12:   required from ‘s<i, t>& s<i, <template-parameter-1-2>
>::p(const i*, const i*, f::g) [with i = char; <template-parameter-1-2> =
e<char>; f::g = int]’
/tmp/pr90462.C:45:77:   required from here
/tmp/pr90462.C:43:5: note: caret
   43 |   a = r();
      |     ^
(gdb) call inform
(line_table->location_adhoc_data_map.data[3].src_range.m_start, "start")
/tmp/pr90462.C:43:3: note: start
   43 |   a = r();
      |   ^
(gdb) call inform
(line_table->location_adhoc_data_map.data[3].src_range.m_finish, "finish")
cc1plus: note: finish

The unknown finish location is coming from rhs.get_finish () here:

9787                  /* Build the assignment expression.  Its default
9788                     location:
9789                       LHS = RHS
9790                       ~~~~^~~~~
9791                     is the location of the '=' token as the
9792                     caret, ranging from the start of the lhs to the
9793                     end of the rhs.  */
9794                  loc = make_location (loc,
9795                                       expr.get_start (),
9796                                       rhs.get_finish ());

(gdb) p rhs
$6 = {m_value = <call_expr 0x7ffff1a179c0>, m_loc = 0}

where the underlying CALL_EXPR *does* have a location, but the cp_expr isn't
using it for some reason.

So there are three issues here:
- bulletproofing the JSON output against UNKNOWN_LOCATION for
caret/start/finish of ranges
- bulletproofing the JSON output against a NULL file for an expanded_location
(if this somehow occurs)
- finding and fixing the bad finish location

Reply via email to