Bug 82491 - UBSAN in gcc/gimple-fold.c:6187:6: runtime error: signed integer overflow: 9223372036854775807 * 8 cannot be represented in type 'long int'
Summary: UBSAN in gcc/gimple-fold.c:6187:6: runtime error: signed integer overflow: 92...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: unknown
: P3 normal
Target Milestone: 8.0
Assignee: Martin Liška
URL:
Keywords:
Depends on:
Blocks: ubsan
  Show dependency treegraph
 
Reported: 2017-10-09 11:46 UTC by Martin Liška
Modified: 2018-04-03 13:45 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-12-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Liška 2017-10-09 11:46:28 UTC
With bootstrap-ubsan I see:

$ UBSAN_OPTIONS="print_stacktrace=1" ./xgcc -B. /home/marxin/Programming/gcc2/gcc/testsuite/c-c++-common/ubsan/ptr-overflow-sanitization-1.c -fsanitize=undefined -O3 -g
../../gcc/gimple-fold.c:6187:6: runtime error: signed integer overflow: 9223372036854775807 * 8 cannot be represented in type 'long int'
    #0 0x120ea4d in get_base_constructor ../../gcc/gimple-fold.c:6187
    #1 0x121127f in fold_const_aggregate_ref_1(tree_node*, tree_node* (*)(tree_node*)) ../../gcc/gimple-fold.c:6509
    #2 0x1211684 in fold_const_aggregate_ref(tree_node*) ../../gcc/gimple-fold.c:6548
    #3 0x11ef391 in maybe_fold_reference ../../gcc/gimple-fold.c:296
    #4 0x1207bd2 in fold_stmt_1 ../../gcc/gimple-fold.c:4651
    #5 0x1207fc9 in fold_stmt(gimple_stmt_iterator*, tree_node* (*)(tree_node*)) ../../gcc/gimple-fold.c:4739
    #6 0x2226772 in substitute_and_fold_dom_walker::before_dom_children(basic_block_def*) ../../gcc/tree-ssa-propagate.c:1072
    #7 0x36f262c in dom_walker::walk(basic_block_def*) ../../gcc/domwalk.c:308
    #8 0x2227186 in substitute_and_fold(tree_node* (*)(tree_node*), bool (*)(gimple_stmt_iterator*)) ../../gcc/tree-ssa-propagate.c:1188
    #9 0x2048303 in ccp_finalize ../../gcc/tree-ssa-ccp.c:960
    #10 0x2054465 in do_ssa_ccp ../../gcc/tree-ssa-ccp.c:2437
    #11 0x205477a in execute ../../gcc/tree-ssa-ccp.c:2480
    #12 0x18f223a in execute_one_pass(opt_pass*) ../../gcc/passes.c:2495
    #13 0x18f2bcb in execute_pass_list_1 ../../gcc/passes.c:2584
    #14 0x18f2c80 in execute_pass_list_1 ../../gcc/passes.c:2585
    #15 0x18f2d1f in execute_pass_list(function*, opt_pass*) ../../gcc/passes.c:2595
    #16 0x18ed2ef in do_per_function_toporder(void (*)(function*, void*), void*) ../../gcc/passes.c:1737
    #17 0x18f5266 in execute_ipa_pass_list(opt_pass*) ../../gcc/passes.c:2935
    #18 0xd36f41 in ipa_passes ../../gcc/cgraphunit.c:2399
    #19 0xd37db5 in symbol_table::compile() ../../gcc/cgraphunit.c:2534
    #20 0xd38958 in symbol_table::finalize_compilation_unit() ../../gcc/cgraphunit.c:2692
    #21 0x1cdc527 in compile_file ../../gcc/toplev.c:481
    #22 0x1ce2c84 in do_compile ../../gcc/toplev.c:2037
    #23 0x1ce32b3 in toplev::main(int, char**) ../../gcc/toplev.c:2172
    #24 0x3aaf9e0 in main ../../gcc/main.c:39
    #25 0x14eeb648cf49 in __libc_start_main (/lib64/libc.so.6+0x20f49)
    #26 0x7d93b9 in _start (/home/marxin/Programming/gcc2/objdir/gcc/cc1+0x7d93b9)

../../gcc/dwarf2out.c:13598:15: runtime error: signed integer overflow: 9223372036854775789 + 48 cannot be represented in type 'long int'
    #0 0xea2524 in based_loc_descr ../../gcc/dwarf2out.c:13598
    #1 0xeb0bfd in mem_loc_descriptor(rtx_def*, machine_mode, machine_mode, var_init_status) ../../gcc/dwarf2out.c:15027
    #2 0xeb93ed in loc_descriptor ../../gcc/dwarf2out.c:15974
    #3 0xeb70d8 in loc_descriptor ../../gcc/dwarf2out.c:15784
    #4 0xeb9cb2 in dw_loc_list_1 ../../gcc/dwarf2out.c:16069
    #5 0xebb348 in dw_loc_list ../../gcc/dwarf2out.c:16339
    #6 0xebff4b in loc_list_from_tree_1 ../../gcc/dwarf2out.c:17454
    #7 0xec33a8 in loc_list_from_tree ../../gcc/dwarf2out.c:18058
    #8 0xecbe1a in add_location_or_const_value_attribute ../../gcc/dwarf2out.c:19263
    #9 0xee0ca2 in gen_variable_die ../../gcc/dwarf2out.c:22928
    #10 0xef0500 in gen_decl_die ../../gcc/dwarf2out.c:25393
    #11 0xeecf4a in process_scope_var ../../gcc/dwarf2out.c:24849
    #12 0xeed02c in decls_for_scope ../../gcc/dwarf2out.c:24875
    #13 0xedcab0 in gen_subprogram_die ../../gcc/dwarf2out.c:22421
    #14 0xeefd6a in gen_decl_die ../../gcc/dwarf2out.c:25310
    #15 0xef296b in dwarf2out_decl ../../gcc/dwarf2out.c:25852
    #16 0xef29f4 in dwarf2out_function_decl ../../gcc/dwarf2out.c:25867
    #17 0x1090964 in rest_of_handle_final ../../gcc/final.c:4520
    #18 0x1090f80 in execute ../../gcc/final.c:4562
    #19 0x18f223a in execute_one_pass(opt_pass*) ../../gcc/passes.c:2495
    #20 0x18f2bcb in execute_pass_list_1 ../../gcc/passes.c:2584
    #21 0x18f2c80 in execute_pass_list_1 ../../gcc/passes.c:2585
    #22 0x18f2c80 in execute_pass_list_1 ../../gcc/passes.c:2585
    #23 0x18f2d1f in execute_pass_list(function*, opt_pass*) ../../gcc/passes.c:2595
    #24 0xd34522 in cgraph_node::expand() ../../gcc/cgraphunit.c:2115
    #25 0xd35b07 in expand_all_functions ../../gcc/cgraphunit.c:2251
    #26 0xd38201 in symbol_table::compile() ../../gcc/cgraphunit.c:2599
    #27 0xd38958 in symbol_table::finalize_compilation_unit() ../../gcc/cgraphunit.c:2692
    #28 0x1cdc527 in compile_file ../../gcc/toplev.c:481
    #29 0x1ce2c84 in do_compile ../../gcc/toplev.c:2037
    #30 0x1ce32b3 in toplev::main(int, char**) ../../gcc/toplev.c:2172
    #31 0x3aaf9e0 in main ../../gcc/main.c:39
    #32 0x14eeb648cf49 in __libc_start_main (/lib64/libc.so.6+0x20f49)
    #33 0x7d93b9 in _start (/home/marxin/Programming/gcc2/objdir/gcc/cc1+0x7d93b9)

../../gcc/dwarf2out.c:13623:11: runtime error: signed integer overflow: -9223372036854775779 + -48 cannot be represented in type 'long int'
    #0 0xea2a10 in based_loc_descr ../../gcc/dwarf2out.c:13623
    #1 0xeb0bfd in mem_loc_descriptor(rtx_def*, machine_mode, machine_mode, var_init_status) ../../gcc/dwarf2out.c:15027
    #2 0xeb93ed in loc_descriptor ../../gcc/dwarf2out.c:15974
    #3 0xeb70d8 in loc_descriptor ../../gcc/dwarf2out.c:15784
    #4 0xeb9cb2 in dw_loc_list_1 ../../gcc/dwarf2out.c:16069
    #5 0xebb348 in dw_loc_list ../../gcc/dwarf2out.c:16339
    #6 0xebff4b in loc_list_from_tree_1 ../../gcc/dwarf2out.c:17454
    #7 0xec33a8 in loc_list_from_tree ../../gcc/dwarf2out.c:18058
    #8 0xecbe1a in add_location_or_const_value_attribute ../../gcc/dwarf2out.c:19263
    #9 0xee0ca2 in gen_variable_die ../../gcc/dwarf2out.c:22928
    #10 0xef0500 in gen_decl_die ../../gcc/dwarf2out.c:25393
    #11 0xeecf4a in process_scope_var ../../gcc/dwarf2out.c:24849
    #12 0xeed02c in decls_for_scope ../../gcc/dwarf2out.c:24875
    #13 0xedcab0 in gen_subprogram_die ../../gcc/dwarf2out.c:22421
    #14 0xeefd6a in gen_decl_die ../../gcc/dwarf2out.c:25310
    #15 0xef296b in dwarf2out_decl ../../gcc/dwarf2out.c:25852
    #16 0xef29f4 in dwarf2out_function_decl ../../gcc/dwarf2out.c:25867
    #17 0x1090964 in rest_of_handle_final ../../gcc/final.c:4520
    #18 0x1090f80 in execute ../../gcc/final.c:4562
    #19 0x18f223a in execute_one_pass(opt_pass*) ../../gcc/passes.c:2495
    #20 0x18f2bcb in execute_pass_list_1 ../../gcc/passes.c:2584
    #21 0x18f2c80 in execute_pass_list_1 ../../gcc/passes.c:2585
    #22 0x18f2c80 in execute_pass_list_1 ../../gcc/passes.c:2585
    #23 0x18f2d1f in execute_pass_list(function*, opt_pass*) ../../gcc/passes.c:2595
    #24 0xd34522 in cgraph_node::expand() ../../gcc/cgraphunit.c:2115
    #25 0xd35b07 in expand_all_functions ../../gcc/cgraphunit.c:2251
    #26 0xd38201 in symbol_table::compile() ../../gcc/cgraphunit.c:2599
    #27 0xd38958 in symbol_table::finalize_compilation_unit() ../../gcc/cgraphunit.c:2692
    #28 0x1cdc527 in compile_file ../../gcc/toplev.c:481
    #29 0x1ce2c84 in do_compile ../../gcc/toplev.c:2037
    #30 0x1ce32b3 in toplev::main(int, char**) ../../gcc/toplev.c:2172
    #31 0x3aaf9e0 in main ../../gcc/main.c:39
    #32 0x14eeb648cf49 in __libc_start_main (/lib64/libc.so.6+0x20f49)
    #33 0x7d93b9 in _start (/home/marxin/Programming/gcc2/objdir/gcc/cc1+0x7d93b9)
Comment 1 Richard Biener 2017-10-09 12:14:47 UTC
      if (!integer_zerop (TREE_OPERAND (base, 1)))
        {
          if (!tree_fits_shwi_p (TREE_OPERAND (base, 1)))
            return NULL_TREE;

the above check isn't enough to catch overflow below.

          *bit_offset += (mem_ref_offset (base).to_short_addr ()
                          * BITS_PER_UNIT);

I suppose doing

  offset_int boff = *bit_offset + mem_ref_offset (base) * BITS_PER_UNIT;
  if (boff.fits_shwi_p ())
    *bit_offset = boff.to_short_addr ();
  else
    return NULL_TREE;

would work.
Comment 2 Martin Liška 2017-12-19 10:20:06 UTC
Let me take it. I'll prepare patch.
Comment 3 Martin Liška 2018-02-16 14:47:31 UTC
I haven't finished that before poly-int went it.
May I please ask Richard Sandiford to help me with the version of the patch after we have poly-int in trunk?
Comment 4 rsandifo@gcc.gnu.org 2018-02-16 19:06:56 UTC
(In reply to Martin Liška from comment #3)
> I haven't finished that before poly-int went it.
> May I please ask Richard Sandiford to help me with the version of the patch
> after we have poly-int in trunk?

The poly_int version of the comment #1 code would be something like:

  poly_offset_int boff = *bit_offset + mem_ref_offset (base) * BITS_PER_UNIT;
  if (!boff.to_shwi (bit_offset))
    return NULL_TREE;
Comment 5 Martin Liška 2018-02-19 10:50:41 UTC
Thanks Richard!

Now I still see the other issue in dwarf2out:

Breakpoint 1, based_loc_descr (reg=0x7ffff51183a8, offset=..., initialized=VAR_INIT_STATUS_INITIALIZED) at ../../gcc/dwarf2out.c:14170
warning: Source file is more recent than executable.
14170		  elim = strip_offset_and_add (elim, &offset);
(gdb) c
Continuing.
../../gcc/poly-int.h:414:21: runtime error: signed integer overflow: 9223372036854775789 + 48 cannot be represented in type 'long int'
    #0 0xaa9c75 in poly_int_pod<1u, long>& poly_int_pod<1u, long>::operator+=<long>(poly_int_pod<1u, long> const&) ../../gcc/poly-int.h:414
    #1 0xaa9266 in strip_offset_and_add(rtx_def*, poly_int_pod<1u, long>*) ../../gcc/rtl.h:4340
    #2 0xd4f022 in based_loc_descr ../../gcc/dwarf2out.c:14170
    #3 0xd5da4c in mem_loc_descriptor(rtx_def*, machine_mode, machine_mode, var_init_status) ../../gcc/dwarf2out.c:15643
    #4 0xd65a2a in loc_descriptor ../../gcc/dwarf2out.c:16616
...

(gdb) p debug_rtx(elim)
(plus:DI (reg/f:DI 7 sp)
    (const_int 48 [0x30]))
$2 = void
(gdb) p offset
$3 = {<poly_int_pod<1, long>> = {coeffs = {9223372036854775789}}, <No data fields>}

Is it Jakub something we should handle? Do you have a suggestion how to do that?
Comment 6 Martin Liška 2018-02-19 18:30:24 UTC
Author: marxin
Date: Mon Feb 19 18:29:52 2018
New Revision: 257816

URL: https://gcc.gnu.org/viewcvs?rev=257816&root=gcc&view=rev
Log:
Fix ubsan in gimple-fold.c (PR tree-optimization/82491).

2018-02-19  Martin Liska  <mliska@suse.cz>
	    Richard Sandiford  <richard.sandiford@linaro.org>

	PR tree-optimization/82491
	* gimple-fold.c (get_base_constructor): Make earlier bail out
	to prevent ubsan.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/gimple-fold.c
Comment 7 Jakub Jelinek 2018-03-15 14:50:51 UTC
(In reply to Martin Liška from comment #5)
> Thanks Richard!
> 
> Now I still see the other issue in dwarf2out:
> 
> Breakpoint 1, based_loc_descr (reg=0x7ffff51183a8, offset=...,
> initialized=VAR_INIT_STATUS_INITIALIZED) at ../../gcc/dwarf2out.c:14170
> warning: Source file is more recent than executable.
> 14170		  elim = strip_offset_and_add (elim, &offset);
> (gdb) c
> Continuing.
> ../../gcc/poly-int.h:414:21: runtime error: signed integer overflow:
> 9223372036854775789 + 48 cannot be represented in type 'long int'
>     #0 0xaa9c75 in poly_int_pod<1u, long>& poly_int_pod<1u,
> long>::operator+=<long>(poly_int_pod<1u, long> const&)
> ../../gcc/poly-int.h:414
>     #1 0xaa9266 in strip_offset_and_add(rtx_def*, poly_int_pod<1u, long>*)
> ../../gcc/rtl.h:4340
>     #2 0xd4f022 in based_loc_descr ../../gcc/dwarf2out.c:14170
>     #3 0xd5da4c in mem_loc_descriptor(rtx_def*, machine_mode, machine_mode,
> var_init_status) ../../gcc/dwarf2out.c:15643
>     #4 0xd65a2a in loc_descriptor ../../gcc/dwarf2out.c:16616
> ...
> 
> (gdb) p debug_rtx(elim)
> (plus:DI (reg/f:DI 7 sp)
>     (const_int 48 [0x30]))
> $2 = void
> (gdb) p offset
> $3 = {<poly_int_pod<1, long>> = {coeffs = {9223372036854775789}}, <No data
> fields>}
> 
> Is it Jakub something we should handle? Do you have a suggestion how to do
> that?

Dunno, either perform the calculation in poly_uint64 instead and then cast to poly_int64, or don't do it at all if there is overflow.
Comment 8 Martin Liška 2018-03-21 09:02:47 UTC
(In reply to Jakub Jelinek from comment #7)
> (In reply to Martin Liška from comment #5)
> > Thanks Richard!
> > 
> > Now I still see the other issue in dwarf2out:
> > 
> > Breakpoint 1, based_loc_descr (reg=0x7ffff51183a8, offset=...,
> > initialized=VAR_INIT_STATUS_INITIALIZED) at ../../gcc/dwarf2out.c:14170
> > warning: Source file is more recent than executable.
> > 14170		  elim = strip_offset_and_add (elim, &offset);
> > (gdb) c
> > Continuing.
> > ../../gcc/poly-int.h:414:21: runtime error: signed integer overflow:
> > 9223372036854775789 + 48 cannot be represented in type 'long int'
> >     #0 0xaa9c75 in poly_int_pod<1u, long>& poly_int_pod<1u,
> > long>::operator+=<long>(poly_int_pod<1u, long> const&)
> > ../../gcc/poly-int.h:414
> >     #1 0xaa9266 in strip_offset_and_add(rtx_def*, poly_int_pod<1u, long>*)
> > ../../gcc/rtl.h:4340
> >     #2 0xd4f022 in based_loc_descr ../../gcc/dwarf2out.c:14170
> >     #3 0xd5da4c in mem_loc_descriptor(rtx_def*, machine_mode, machine_mode,
> > var_init_status) ../../gcc/dwarf2out.c:15643
> >     #4 0xd65a2a in loc_descriptor ../../gcc/dwarf2out.c:16616
> > ...
> > 
> > (gdb) p debug_rtx(elim)
> > (plus:DI (reg/f:DI 7 sp)
> >     (const_int 48 [0x30]))
> > $2 = void
> > (gdb) p offset
> > $3 = {<poly_int_pod<1, long>> = {coeffs = {9223372036854775789}}, <No data
> > fields>}
> > 
> > Is it Jakub something we should handle? Do you have a suggestion how to do
> > that?
> 
> Dunno, either perform the calculation in poly_uint64 instead and then cast
> to poly_int64, or don't do it at all if there is overflow.

Richard, may I ask you please one more time for poly_int hint how to write overflow checking?
Comment 9 rsandifo@gcc.gnu.org 2018-03-21 12:58:40 UTC
(In reply to Martin Liška from comment #8)
> (In reply to Jakub Jelinek from comment #7)
> > Dunno, either perform the calculation in poly_uint64 instead and then cast
> > to poly_int64, or don't do it at all if there is overflow.
> 
> Richard, may I ask you please one more time for poly_int hint how to write
> overflow checking?

What Jakub said about using poly_uint64 for the calculations
sounds right in this context.  CONST_INTs (and thus CONST_INT
offsets) aren't inherently signed or unsigned.
Comment 10 Martin Liška 2018-04-03 13:43:53 UTC
Author: marxin
Date: Tue Apr  3 13:43:22 2018
New Revision: 259030

URL: https://gcc.gnu.org/viewcvs?rev=259030&root=gcc&view=rev
Log:
Remove UBSAN in dwarf2out.c (PR tree-optimization/82491).

2018-04-03  Martin Liska  <mliska@suse.cz>

	PR tree-optimization/82491
	* rtl.h (strip_offset_and_add): Replace += suboffset with
	poly_uint64 () + suboffset.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/rtl.h
Comment 11 Martin Liška 2018-04-03 13:45:33 UTC
Fixed.