[Bug middle-end/89725] ICE in get_fnname_from_decl, at varasm.c:1723

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Mar 27 18:47:00 GMT 2019


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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2019-03-27
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org,
                   |                            |rsandifo at gcc dot gnu.org,
                   |                            |spop at gcc dot gnu.org
     Ever confirmed|0                           |1

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
There are two bugs here.

One minor, that get_fnname_from_decl is really a RTL function and the json
stuff shouldn't use that, if it wants the assembler name, it should use say
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))
if it wants a printable name then current_function_name ().

The more important bug is buffer overflow in tree-data-ref.c.

build_classic_dist_vector is called on following ddr and loop_nest 3:

(Data Dep: 
#(Data Ref: 
#  bb: 5 
#  stmt: M0[i_87][ii_92][1][jj_93] = _6;
#  ref: M0[i_87][ii_92][1][jj_93];
#  base_object: M0;
#  Access function 0: {0, +, 1}_2
#  Access function 1: 1
#  Access function 2: {0, +, 1}_3
#  Access function 3: {0, +, 1}_5
#)
#(Data Ref: 
#  bb: 5 
#  stmt: _7 = M0[i_87][ii_92][j_91][jj_93];
#  ref: M0[i_87][ii_92][j_91][jj_93];
#  base_object: M0;
#  Access function 0: {0, +, 1}_2
#  Access function 1: {0, +, 1}_4
#  Access function 2: {0, +, 1}_3
#  Access function 3: {0, +, 1}_5
#)
  access_fn_A: {0, +, 1}_2
  access_fn_B: {0, +, 1}_2

 (subscript 
  iterations_that_access_an_element_twice_in_A: [0]
  last_conflict: scev_not_known
  iterations_that_access_an_element_twice_in_B: [0]
  last_conflict: scev_not_known
  (Subscript distance: 0 ))
  access_fn_A: 1
  access_fn_B: {0, +, 1}_4

 (subscript 
  iterations_that_access_an_element_twice_in_A: [0]
  last_conflict: 1
  iterations_that_access_an_element_twice_in_B: [1]
  last_conflict: 1
  (Subscript distance: -1 ))
  access_fn_A: {0, +, 1}_3
  access_fn_B: {0, +, 1}_3

 (subscript 
  iterations_that_access_an_element_twice_in_A: [0]
  last_conflict: scev_not_known
  iterations_that_access_an_element_twice_in_B: [0]
  last_conflict: scev_not_known
  (Subscript distance: 0 ))
  access_fn_A: {0, +, 1}_5
  access_fn_B: {0, +, 1}_5

 (subscript 
  iterations_that_access_an_element_twice_in_A: [0]
  last_conflict: scev_not_known
  iterations_that_access_an_element_twice_in_B: [0]
  last_conflict: scev_not_known
  (Subscript distance: 0 ))
  inner loop index: 0
  loop nest: (3 4 5 )
)

DDR_NB_LOOPS (ddr) is 3 - the (3 4 5 ) loop nest, but when processing the first
of the 4 subscripts by build_classic_dist_vector_1,
access_fn_a and access_fn_b are both {0, +, 1}_2, so var_a is 2, *index_carry
is also initially 3
          dist = int_cst_value (SUB_DISTANCE (subscript));
          index = index_in_loop_nest (var_a, DDR_LOOP_NEST (ddr));
          *index_carry = MIN (index, *index_carry);
and as 2 is not found in the DDR_LOOP_NEST (ddr), it returns 3, but both dist_v
and init_v are only pointers to 3 HOST_WIDE_INTs, so
if (init_v[index] != 0 && dist_v[index] != dist)
are already reads after end of vectors (so could segfault if nothing is mapped
after them), and as we are unlucky enough that dist_v[index] == dist == 0, we
happily overwrite the SYMBOL_REF at &init_v[3].

Wonder if we should do something like:
  if (index == DDR_NB_LOOPS (ddr))
    {
      non_affine_dependence_relation (ddr);
      return false;
    }
or if there is some other bug somewhere else (e.g. that the loop nest should
never be just (3 4 5 ) when there are _2 ddrs).


More information about the Gcc-bugs mailing list