Bug 96058 - ICE in c_getstr at gcc/fold-const.c:15475
Summary: ICE in c_getstr at gcc/fold-const.c:15475
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 11.0
: P2 normal
Target Milestone: 10.3
Assignee: Martin Sebor
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: mozillametabug
  Show dependency treegraph
 
Reported: 2020-07-04 09:16 UTC by Martin Liška
Modified: 2020-08-18 07:21 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 10.2.1, 11.0
Known to fail:
Last reconfirmed: 2020-07-04 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 2020-07-04 09:16:24 UTC
I see the ICE in a LTRANS when using LTO on chrome. So it's unlikely I can create a reduced-test case:

I'm using GCC 10.1 release:

gcc --version
gcc (SUSE Linux) 10.1.1 20200625 [revision c91e43e9363bd119a695d64505f96539fa451bf2]
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ /usr/lib64/gcc/x86_64-suse-linux/10/lto1 -fltrans chrome.ltrans81.o -quiet
during GIMPLE pass: strlen
../../chrome/browser/ui/views/sharing/sharing_icon_view.cc: In member function ‘GetVectorIconBadge’:
../../chrome/browser/ui/views/sharing/sharing_icon_view.cc:146: internal compiler error: in tree_to_uhwi, at tree.h:4519
0x666aa8 tree_to_uhwi(tree_node const*)
	../../gcc/tree.h:4519
0x666aa8 c_getstr(tree_node*, unsigned long*)
	../../gcc/fold-const.c:15475
0xf54bf2 get_stridx
	../../gcc/tree-ssa-strlen.c:537
0xde690d strlen_dom_walker::before_dom_children(basic_block_def*)
	../../gcc/tree-ssa-strlen.c:5832
0xde5e63 dom_walker::walk(basic_block_def*)
	../../gcc/domwalk.c:309
0x1134468 printf_strlen_execute
	../../gcc/tree-ssa-strlen.c:5922
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://bugs.opensuse.org/> for instructions.

(gdb) bt
#0  c_getstr (src=0x7fffeffb0e28, strlen=0x0) at ../../gcc/fold-const.c:15475
#1  0x0000000000f54bf3 in get_stridx (exp=0x7fffeffa6480, offrng=0x0, rvals=0x0) at ../../gcc/tree-ssa-strlen.c:537
#2  0x0000000000de690e in strlen_dom_walker::before_dom_children (this=0x7fffffffdfa0, bb=0x7fffeffb70d0) at ../../gcc/gimple.h:4539
#3  0x0000000000de5e64 in dom_walker::walk (this=0x7fffffffdfa0, bb=0x7fffeffb70d0) at ../../gcc/domwalk.c:309
#4  0x0000000001134469 in (anonymous namespace)::printf_strlen_execute (fun=0x7ffff0988bb0, warn_only=<optimized out>) at ../../gcc/tree-ssa-strlen.c:5922
#5  0x0000000000d49063 in execute_one_pass (pass=0x1d00a50) at ../../gcc/passes.c:2502
#6  0x0000000000d7e825 in execute_pass_list_1 (pass=0x1d00a50) at ../../gcc/passes.c:2590
#7  execute_pass_list_1 (pass=0x1cfe680) at ../../gcc/passes.c:2591
#8  execute_pass_list (fn=0x7ffff0988bb0, pass=<optimized out>) at ../../gcc/passes.c:2601
#9  0x000000000111bc42 in cgraph_node::expand (this=0x7ffff6fbee10) at ../../gcc/cgraphunit.c:2300
#10 0x000000000110f6a6 in expand_all_functions () at ../../gcc/cgraphunit.c:2471
#11 symbol_table::compile (this=0x7ffff7754100) at ../../gcc/cgraphunit.c:2822
#12 0x00000000010fdeab in lto_main () at ../../gcc/lto/lto.c:653
#13 0x00000000010fa1be in compile_file () at ../../gcc/toplev.c:458
#14 0x00000000010c7ffa in do_compile () at ../../gcc/toplev.c:2278
#15 toplev::main (this=this@entry=0x7fffffffe23e, argc=<optimized out>, argv=<optimized out>) at ../../gcc/toplev.c:2417
#16 0x00000000010c73cc in main (argc=<optimized out>, argv=<optimized out>) at ../../gcc/main.c:39
(gdb) p debug_tree(exp)
No symbol "exp" in current context.
(gdb) p debug_tree(src)
 <string_cst 0x7fffeffb0e28
    type <array_type 0x7fffeff55888
        type <record_type 0x7ffff7701e70 VectorIcon readonly cxx-odr-p VOID
            align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff4460000 context <namespace_decl 0x7ffff7581390 gfx>
            pointer_to_this <pointer_type 0x7ffff7701f18> reference_to_this <reference_type 0x7ffff5ddfb28>>
        BLK
        align:8 warn_if_not_align:0 symtab:0 alias-set -1 structural-equality
        domain <integer_type 0x7fffeff55738 type <integer_type 0x7ffff7766000 sizetype>
            DI
            size <integer_cst 0x7ffff7751bb8 constant 64>
            unit-size <integer_cst 0x7ffff7751bd0 constant 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7fffeff55738 precision:64 min <integer_cst 0x7ffff7751be8 0> max <integer_cst 0x7ffff76ba498 23>>>
    readonly constant static "\000">
$1 = void

(gdb) p debug_tree(elttype)
No symbol "elttype" in current context.
(gdb) p debug_tree(eltype)
 <record_type 0x7ffff7701e70 VectorIcon readonly cxx-odr-p VOID
    align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff4460000 context <namespace_decl 0x7ffff7581390 gfx>
    pointer_to_this <pointer_type 0x7ffff7701f18> reference_to_this <reference_type 0x7ffff5ddfb28>>
$2 = void

(gdb) p debug_generic_expr (exp)
&kNoneIcon
(gdb) p debug_function(current_function_decl, 0)
GetVectorIconBadge (const struct SharingIconView * const this)
{
  bool _1;
  const struct VectorIcon * _2;

  <bb 2> [local count: 1073741824]:
  _1 = this_4(D)->should_show_error_;
  if (_1 != 0)
    goto <bb 3>; [50.00%]
  else
    goto <bb 4>; [50.00%]

  <bb 3> [local count: 536870912]:

  <bb 4> [local count: 1073741824]:
  # _2 = PHI <&kNoneIcon(2), &kBlockedBadgeIcon(3)>
  return _2;

}

Will you be Martin able to fix it with the provided info?
Comment 1 Martin Liška 2020-07-04 09:19:41 UTC
There's a ltrans file:
https://drive.google.com/file/d/1cddbnb886aVn1vfpJMLIRc1Ue3dyBuTy/view?usp=sharing

The ICE happens with c91e43e9363bd119a695d64505f96539fa451bf2 revision (one needs zstd compression enabled).
Comment 2 Andrew Pinski 2020-07-04 14:09:01 UTC
Multi delta should be able to reduce this. Normally reduce which .o files are needed and then reduce the .ii files that needed to produce the .o files is the way to reduce this ...
Comment 3 Martin Liška 2020-07-04 16:33:35 UTC
(In reply to Andrew Pinski from comment #2)
> Multi delta should be able to reduce this. Normally reduce which .o files
> are needed and then reduce the .ii files that needed to produce the .o files
> is the way to reduce this ...

I know how to make a reduction of a LTO test-case, but WPA and LTRANS compilation takes 1 hour. It's waste of time doing such a reduction.
Comment 4 Richard Biener 2020-07-06 07:19:30 UTC
We have an array type of an incomplete type which should be impossible.
Likewise a STRING_CST of array-of-struct type shouldn't exist either.  You
could instrument the LTO out-streaming code to detect this case and thus
identify the problematic source TU.
Comment 5 Martin Liška 2020-07-07 11:51:27 UTC
So the corrupted STRING_CST is created in LTRANS here:

gcc/expr.c:

   │11714         if (TREE_CODE (init) == CONSTRUCTOR && initializer_zerop (init))  
   │11715           {                                                                 
   │11716             /* Fold an empty/zero constructor for an implicitly initialized 
   │11717                object or subobject into the empty string.  */         
   │11718                                                                       
   │11719             /* Determine the character type from that of the original 
   │11720                expression.  */  
B+ │11721             tree chartype = argtype;
   │11722             if (POINTER_TYPE_P (chartype))
   │11723               chartype = TREE_TYPE (chartype);
   │11724             while (TREE_CODE (chartype) == ARRAY_TYPE)
   │11725               chartype = TREE_TYPE (chartype);
   │11726             /* Convert a char array to an empty STRING_CST having an array

(gdb) p debug_tree(init)
 <constructor 0x7ffff0185120
    type <record_type 0x7ffff4514000 VectorIcon addressable cxx-odr-p BLK
        size <integer_cst 0x7ffff7824078 constant 192>
        unit-size <integer_cst 0x7ffff7824048 constant 24>
        align:64 warn_if_not_align:0 symtab:0 alias-set 407 canonical-type 0x7ffff4514000
        fields <field_decl 0x7ffff450ebe0 reps type <pointer_type 0x7ffff450df18>
            readonly unsigned nonlocal DI ../../ui/gfx/vector_icon_types.h:102:0
            size <integer_cst 0x7ffff7806bb8 constant 64>
            unit-size <integer_cst 0x7ffff7806bd0 constant 8>
            align:64 warn_if_not_align:0 offset_align 128
            offset <integer_cst 0x7ffff7806be8 constant 0>
            bit-offset <integer_cst 0x7ffff7806c30 constant 0> context <record_type 0x7ffff4514000 VectorIcon> chain <field_decl 0x7ffff450eb48 reps_size>> context <namespace_decl 0x7ffff7635390 gfx>
        pointer_to_this <pointer_type 0x7ffff0114150>>
    constant length:3
    idx <field_decl 0x7ffff450ebe0 reps
        type <pointer_type 0x7ffff450df18 type <record_type 0x7ffff450ddc8 VectorIconRep>
            readonly unsigned DI size <integer_cst 0x7ffff7806bb8 64> unit-size <integer_cst 0x7ffff7806bd0 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 structural-equality>
        readonly unsigned nonlocal DI ../../ui/gfx/vector_icon_types.h:102:0 size <integer_cst 0x7ffff7806bb8 64> unit-size <integer_cst 0x7ffff7806bd0 8>
        align:64 warn_if_not_align:0 offset_align 128 offset <integer_cst 0x7ffff7806be8 0> bit-offset <integer_cst 0x7ffff7806c30 0> context <record_type 0x7ffff4514000 VectorIcon>
        chain <field_decl 0x7ffff450eb48 reps_size type <integer_type 0x7ffff760c150 size_t>
            unsigned nonlocal DI ../../ui/gfx/vector_icon_types.h:103:0 size <integer_cst 0x7ffff7806bb8 64> unit-size <integer_cst 0x7ffff7806bd0 8>
            align:64 warn_if_not_align:0 offset_align 128 offset <integer_cst 0x7ffff7806be8 0> bit-offset <integer_cst 0x7ffff7806bb8 64> context <record_type 0x7ffff4514000 VectorIcon> chain <field_decl 0x7ffff450eab0 name>>>
    val <integer_cst 0x7ffff1f36fc0 type <pointer_type 0x7ffff437ec78> constant 0>
    idx <field_decl 0x7ffff450eb48 reps_size
        type <integer_type 0x7ffff760c150 size_t public unsigned DI size <integer_cst 0x7ffff7806bb8 64> unit-size <integer_cst 0x7ffff7806bd0 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff781b738 precision:64 min <integer_cst 0x7ffff7806e88 0> max <integer_cst 0x7ffff7807500 18446744073709551615>
            pointer_to_this <pointer_type 0x7ffff61c8498> reference_to_this <reference_type 0x7ffff31cc3f0>>
        unsigned nonlocal DI ../../ui/gfx/vector_icon_types.h:103:0 size <integer_cst 0x7ffff7806bb8 64> unit-size <integer_cst 0x7ffff7806bd0 8>
        align:64 warn_if_not_align:0 offset_align 128 offset <integer_cst 0x7ffff7806be8 0> bit-offset <integer_cst 0x7ffff7806bb8 64> context <record_type 0x7ffff4514000 VectorIcon>
        chain <field_decl 0x7ffff450eab0 name type <pointer_type 0x7ffff76b2dc8>
            unsigned nonlocal DI ../../ui/gfx/vector_icon_types.h:108:0 size <integer_cst 0x7ffff7806bb8 64> unit-size <integer_cst 0x7ffff7806bd0 8>
            align:64 warn_if_not_align:0 offset_align 128
            offset <integer_cst 0x7ffff7806c18 constant 16> bit-offset <integer_cst 0x7ffff7806c30 0> context <record_type 0x7ffff4514000 VectorIcon>>>
    val <integer_cst 0x7ffff29b9f30 type <integer_type 0x7ffff760c150 size_t> constant 0>
    idx <field_decl 0x7ffff450eab0 name
        type <pointer_type 0x7ffff76b2dc8 type <integer_type 0x7ffff76402a0 char>
            public unsigned DI size <integer_cst 0x7ffff7806bb8 64> unit-size <integer_cst 0x7ffff7806bd0 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set 409 structural-equality
            pointer_to_this <pointer_type 0x7ffff522adc8> reference_to_this <reference_type 0x7ffff3176f18>>
        unsigned nonlocal DI ../../ui/gfx/vector_icon_types.h:108:0 size <integer_cst 0x7ffff7806bb8 64> unit-size <integer_cst 0x7ffff7806bd0 8>
        align:64 warn_if_not_align:0 offset_align 128 offset <integer_cst 0x7ffff7806c18 16> bit-offset <integer_cst 0x7ffff7806c30 0> context <record_type 0x7ffff4514000 VectorIcon>>
    val <integer_cst 0x7ffff29b9e40 type <pointer_type 0x7ffff76b2dc8> constant 0>>
$18 = void

(gdb) p debug_tree(argtype)
 <pointer_type 0x7ffff77b5f18
    type <record_type 0x7ffff77b5e70 VectorIcon readonly cxx-odr-p VOID
        align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff4514000 context <namespace_decl 0x7ffff7635390 gfx>
        pointer_to_this <pointer_type 0x7ffff77b5f18> reference_to_this <reference_type 0x7ffff5e93b28>>
    public unsigned DI
    size <integer_cst 0x7ffff7806bb8 type <integer_type 0x7ffff781b0a8 bitsizetype> constant 64>
    unit-size <integer_cst 0x7ffff7806bd0 type <integer_type 0x7ffff781b000 sizetype> constant 8>
    align:64 warn_if_not_align:0 symtab:0 alias-set 1025 structural-equality>

(gdb) p debug_tree(chartype)
 <record_type 0x7ffff77b5e70 VectorIcon readonly cxx-odr-p VOID
    align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff4514000 context <namespace_decl 0x7ffff7635390 gfx>
    pointer_to_this <pointer_type 0x7ffff77b5f18> reference_to_this <reference_type 0x7ffff5e93b28>>
$21 = void

@Martin: Can you please take a look?
Comment 6 Martin Sebor 2020-07-07 17:59:50 UTC
The stack trace in comment #0:

during GIMPLE pass: strlen
../../chrome/browser/ui/views/sharing/sharing_icon_view.cc: In member function ‘GetVectorIconBadge’:
../../chrome/browser/ui/views/sharing/sharing_icon_view.cc:146: internal compiler error: in tree_to_uhwi, at tree.h:4519
0x666aa8 tree_to_uhwi(tree_node const*)
	../../gcc/tree.h:4519
0x666aa8 c_getstr(tree_node*, unsigned long*)
	../../gcc/fold-const.c:15475

indicates that tree_to_uhwi() ICEs after a successful call to tree_fits_uhwi_p():

  if (!tree_fits_uhwi_p (mem_size))
    return NULL;

  /* STRING_LENGTH is the size of the string literal, including any
     embedded NULs.  STRING_SIZE is the size of the array the string
     literal is stored in.  */
  unsigned HOST_WIDE_INT string_length = TREE_STRING_LENGTH (src);
  unsigned HOST_WIDE_INT string_size = tree_to_uhwi (mem_size);

I don't see how that can ever happen.  Am I misreading it?  What's mem_size?
Comment 7 Jakub Jelinek 2020-07-07 19:02:07 UTC
(In reply to Martin Sebor from comment #6)
> Am I misreading it?  What's mem_size?

Yes.  See Martin L.'s comment, it is 10.1 release, so the line numbers are slightly different from trunk or current 10 branch.
Obviously the two tree_to_uhwi calls guarded with tree_fits_uhwi_p can't be it, but it is the third one.
      tree eltype = TREE_TYPE (TREE_TYPE (src));
      /* Support only properly NUL-terminated single byte strings.  */
      if (tree_to_uhwi (TYPE_SIZE_UNIT (eltype)) != 1)
        return NULL;
And see #c5 on what it happens.
The string_constant code added in g:14b7950f126f doesn't try to verify that chartype is some character or even integral type, nor whether it is a complete type.
It actually doesn't seem correct even for wchar_t/char16_t/char32_t etc., because initsize is size in bytes.  Nothing tries to verify tree_fits_uhwi_p (initsize) and calls build_string_literal with the chartype and initsize converted to uhwi.
Now, if initsize is HOST_WIDE_INT_M1U, it will do something different, and even if not, build_string_literal assumes that the string has type chartype[size], so whenever chartype is not a byte type, but 2/4/8 byte integer, the string literal will have size that is twice/4/8 times larger type than desired.
Comment 8 Martin Liška 2020-07-08 07:04:09 UTC
Btw. one can debug that with the current releases/gcc-10 branch locally in order to get proper locations.
Thanks Jakub for the analysis.
Comment 9 Richard Biener 2020-07-23 06:51:51 UTC
GCC 10.2 is released, adjusting target milestone.
Comment 10 Martin Liška 2020-07-23 13:41:50 UTC
@Martin: Can you please take a look?
Comment 11 Martin Liška 2020-07-27 10:30:01 UTC
Working on that.
Comment 12 GCC Commits 2020-07-27 14:18:29 UTC
The master branch has been updated by Martin Liska <marxin@gcc.gnu.org>:

https://gcc.gnu.org/g:7355a9408b990cdd20db91e2e1ba0b03e801d6a6

commit r11-2364-g7355a9408b990cdd20db91e2e1ba0b03e801d6a6
Author: Martin Liska <mliska@suse.cz>
Date:   Mon Jul 27 12:30:24 2020 +0200

    expr: build string_constant only for a char type
    
    gcc/ChangeLog:
    
            PR tree-optimization/96058
            * expr.c (string_constant): Build string_constant only
            for a type that has same precision as char_type_node
            and is an integral type.
Comment 13 Martin Liška 2020-07-27 14:22:06 UTC
Fixed on master so far.
Comment 14 GCC Commits 2020-07-28 10:37:02 UTC
The releases/gcc-10 branch has been updated by Martin Liska <marxin@gcc.gnu.org>:

https://gcc.gnu.org/g:c0438ced53bcf57e4ebb1c38c226e41571aca892

commit r10-8542-gc0438ced53bcf57e4ebb1c38c226e41571aca892
Author: Martin Liska <mliska@suse.cz>
Date:   Mon Jul 27 12:30:24 2020 +0200

    expr: build string_constant only for a char type
    
    gcc/ChangeLog:
    
            PR tree-optimization/96058
            * expr.c (string_constant): Build string_constant only
            for a type that has same precision as char_type_node
            and is an integral type.
    
    (cherry picked from commit 7355a9408b990cdd20db91e2e1ba0b03e801d6a6)
Comment 15 Martin Liška 2020-07-28 10:39:23 UTC
Fixed on GCC 10 as well.
Comment 16 Arseny Solokha 2020-08-18 06:47:55 UTC
Is there any work pending?
Comment 17 Martin Liška 2020-08-18 07:21:43 UTC
(In reply to Arseny Solokha from comment #16)
> Is there any work pending?

No, that's for reminder.
Comment 18 Martin Liška 2020-08-18 07:21:53 UTC
*thanks for reminder