Bug 78548 - [7 Regression ]ICE on valid C code on x86_64-linux-gnu at -O2 and -O3 in 64-bit mode with -Wall (*** Error in `/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/cc1': double free or corruption (fasttop): 0x0000000003c15810 ***)
Summary: [7 Regression ]ICE on valid C code on x86_64-linux-gnu at -O2 and -O3 in 64-b...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 7.0
: P1 normal
Target Milestone: 7.0
Assignee: Aldy Hernandez
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2016-11-27 12:17 UTC by Chengnian Sun
Modified: 2016-12-06 10:38 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 6.2.1
Known to fail:
Last reconfirmed: 2016-11-29 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chengnian Sun 2016-11-27 12:17:24 UTC
The following program crashes gcc in the 64-bit mode, but causes gcc to hang in the 32-bit mode. 

$ gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-source-trunk/configure --enable-languages=c,c++,lto --prefix=/usr/local/gcc-trunk --disable-bootstrap
Thread model: posix
gcc version 7.0.0 20161127 (experimental) [trunk revision 242892] (GCC) 
$ 
$ gcc-trunk -Wall -w -O3 -m64 small.c
*** Error in `/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/cc1': double free or corruption (fasttop): 0x0000000003c15810 ***
small.c: In function ‘main’:
small.c:6:5: internal compiler error: Aborted
 int main (  ) {
     ^~~~
0xbe8aff crash_signal
	../../gcc-source-trunk/gcc/toplev.c:333
0xe0ba36 xcallocator<gimple*>::data_free(gimple**)
	../../gcc-source-trunk/gcc/hash-table.h:273
0xe0ba36 ~hash_table
	../../gcc-source-trunk/gcc/hash-table.h:627
0xe0ba36 ~hash_set
	../../gcc-source-trunk/gcc/hash-set.h:25
0xe0ba36 find_def_preds
	../../gcc-source-trunk/gcc/tree-ssa-uninit.c:775
0xe0ba36 is_use_properly_guarded
	../../gcc-source-trunk/gcc/tree-ssa-uninit.c:2375
0xe0c17e find_uninit_use
	../../gcc-source-trunk/gcc/tree-ssa-uninit.c:2434
0xe0c17e warn_uninitialized_phi
	../../gcc-source-trunk/gcc/tree-ssa-uninit.c:2504
0xe0c17e execute
	../../gcc-source-trunk/gcc/tree-ssa-uninit.c:2612
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
$ 
$ cat small.c
char a;
int b;
unsigned c, d;
short e;
int main_f;
int main (  ) {
L0:
    if ( e )     goto L1;
    b = c & d || a;
    if ( !c )     printf ( "", ( long long ) main_f );
    if ( d || !c )     {
        printf ( "%llu\n", ( long long ) main );
        goto L2;
    }
    unsigned g = b;
L1:
    b = g;
L2:
    if ( b )     goto L0;
  return 0;
}
Comment 1 Richard Biener 2016-11-28 09:10:51 UTC
Works on the GCC 6 branch (but I also fail to reproduce on trunk)
Comment 2 Zhendong Su 2016-11-28 09:21:21 UTC
I can still reproduce it with r242892 with "-Wall -w -O3 -m64".  Interestingly, without "-m64", GCC hangs, instead of crashing. 


$ gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-source-trunk/configure --enable-languages=c,c++,lto --prefix=/usr/local/gcc-trunk --disable-bootstrap
Thread model: posix
gcc version 7.0.0 20161127 (experimental) [trunk revision 242892] (GCC) 
$ 
$ gcc-trunk -Wall -w -O3 -m64 small.c
*** Error in `/usr/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/cc1': double free or corruption (fasttop): 0x00000000038273b0 ***
small.c: In function ‘main’:
small.c:6:5: internal compiler error: Aborted
 int main (  ) {
     ^~~~
0xbfe10f crash_signal
	../../gcc-source-trunk/gcc/toplev.c:333
0xe1c630 xcallocator<gimple*>::data_free(gimple**)
	../../gcc-source-trunk/gcc/hash-table.h:273
0xe1c630 ~hash_table
	../../gcc-source-trunk/gcc/hash-table.h:627
0xe1c630 ~hash_set
	../../gcc-source-trunk/gcc/hash-set.h:25
0xe1c630 find_def_preds
	../../gcc-source-trunk/gcc/tree-ssa-uninit.c:775
0xe1c630 is_use_properly_guarded
	../../gcc-source-trunk/gcc/tree-ssa-uninit.c:2375
0xe1da0a find_uninit_use
	../../gcc-source-trunk/gcc/tree-ssa-uninit.c:2434
0xe1da0a warn_uninitialized_phi
	../../gcc-source-trunk/gcc/tree-ssa-uninit.c:2504
0xe1da0a execute
	../../gcc-source-trunk/gcc/tree-ssa-uninit.c:2612
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
$
Comment 3 Martin Liška 2016-11-28 09:25:22 UTC
Confirmed, started with r242639.
Comment 4 Jakub Jelinek 2016-11-29 08:16:00 UTC
==7340== Invalid read of size 4
==7340==    at 0x10EC264: vec<pred_info, va_heap, vl_embed>::length() const (vec.h:458)
==7340==    by 0x10EB994: vec<pred_info, va_heap, vl_ptr>::length() const (in /usr/src/gcc/obj/gcc/cc1)
==7340==    by 0x10E8CBE: simplify_preds_2(vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*) (tree-ssa-uninit.c:1589)
==7340==    by 0x10E9615: simplify_preds(vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*, gimple*, bool) (tree-ssa-uninit.c:1809)
==7340==    by 0x10EA66D: uninit_ops_invalidate_phi_use(gphi*, unsigned int, vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>) (tree-ssa-uninit.c:2290)
==7340==    by 0x10EA812: is_use_properly_guarded(gimple*, basic_block_def*, gphi*, unsigned int, vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2365)
==7340==    by 0x10EAA4D: find_uninit_use(gphi*, unsigned int, vec<gphi*, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2434)
==7340==    by 0x10EACAA: warn_uninitialized_phi(gphi*, vec<gphi*, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2504)
==7340==    by 0x10EB1B3: (anonymous namespace)::pass_late_warn_uninitialized::execute(function*) (tree-ssa-uninit.c:2612)
==7340==    by 0xD36EB2: execute_one_pass(opt_pass*) (passes.c:2370)
==7340==    by 0xD37201: execute_pass_list_1(opt_pass*) (passes.c:2459)
==7340==    by 0xD37232: execute_pass_list_1(opt_pass*) (passes.c:2460)
==7340==  Address 0xbc8b534 is 4 bytes inside a block of size 104 free'd
==7340==    at 0x4A07D6A: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==7340==    by 0x10EC2FA: void va_heap::release<pred_info>(vec<pred_info, va_heap, vl_embed>*&) (vec.h:307)
==7340==    by 0x10EBA07: vec<pred_info, va_heap, vl_ptr>::release() (vec.h:1497)
==7340==    by 0x10E7992: destroy_predicate_vecs(vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*) (tree-ssa-uninit.c:859)
==7340==    by 0x10E9511: simplify_preds_4(vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*) (tree-ssa-uninit.c:1777)
==7340==    by 0x10E963D: simplify_preds(vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*, gimple*, bool) (tree-ssa-uninit.c:1817)
==7340==    by 0x10EA66D: uninit_ops_invalidate_phi_use(gphi*, unsigned int, vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>) (tree-ssa-uninit.c:2290)
==7340==    by 0x10EA812: is_use_properly_guarded(gimple*, basic_block_def*, gphi*, unsigned int, vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2365)
==7340==    by 0x10EAA4D: find_uninit_use(gphi*, unsigned int, vec<gphi*, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2434)
==7340==    by 0x10EACAA: warn_uninitialized_phi(gphi*, vec<gphi*, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2504)
==7340==    by 0x10EB1B3: (anonymous namespace)::pass_late_warn_uninitialized::execute(function*) (tree-ssa-uninit.c:2612)
==7340==    by 0xD36EB2: execute_one_pass(opt_pass*) (passes.c:2370)

is the first bug reported by valgrind and the fatal action is likely a double free:
==7340== Invalid free() / delete / delete[] / realloc()
==7340==    at 0x4A07D6A: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==7340==    by 0x10EC2FA: void va_heap::release<pred_info>(vec<pred_info, va_heap, vl_embed>*&) (vec.h:307)
==7340==    by 0x10EBA07: vec<pred_info, va_heap, vl_ptr>::release() (vec.h:1497)
==7340==    by 0x10E7992: destroy_predicate_vecs(vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*) (tree-ssa-uninit.c:859)
==7340==    by 0x10EA280: normalize_preds(vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>, gimple*, bool) (tree-ssa-uninit.c:2149)
==7340==    by 0x10EA68D: uninit_ops_invalidate_phi_use(gphi*, unsigned int, vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>) (tree-ssa-uninit.c:2292)
==7340==    by 0x10EA812: is_use_properly_guarded(gimple*, basic_block_def*, gphi*, unsigned int, vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2365)
==7340==    by 0x10EAA4D: find_uninit_use(gphi*, unsigned int, vec<gphi*, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2434)
==7340==    by 0x10EACAA: warn_uninitialized_phi(gphi*, vec<gphi*, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2504)
==7340==    by 0x10EB1B3: (anonymous namespace)::pass_late_warn_uninitialized::execute(function*) (tree-ssa-uninit.c:2612)
==7340==    by 0xD36EB2: execute_one_pass(opt_pass*) (passes.c:2370)
==7340==    by 0xD37201: execute_pass_list_1(opt_pass*) (passes.c:2459)
==7340==  Address 0xbc8b530 is 0 bytes inside a block of size 104 free'd
==7340==    at 0x4A07D6A: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==7340==    by 0x10EC2FA: void va_heap::release<pred_info>(vec<pred_info, va_heap, vl_embed>*&) (vec.h:307)
==7340==    by 0x10EBA07: vec<pred_info, va_heap, vl_ptr>::release() (vec.h:1497)
==7340==    by 0x10E7992: destroy_predicate_vecs(vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*) (tree-ssa-uninit.c:859)
==7340==    by 0x10E9511: simplify_preds_4(vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*) (tree-ssa-uninit.c:1777)
==7340==    by 0x10E963D: simplify_preds(vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*, gimple*, bool) (tree-ssa-uninit.c:1817)
==7340==    by 0x10EA66D: uninit_ops_invalidate_phi_use(gphi*, unsigned int, vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>) (tree-ssa-uninit.c:2290)
==7340==    by 0x10EA812: is_use_properly_guarded(gimple*, basic_block_def*, gphi*, unsigned int, vec<vec<pred_info, va_heap, vl_ptr>, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2365)
==7340==    by 0x10EAA4D: find_uninit_use(gphi*, unsigned int, vec<gphi*, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2434)
==7340==    by 0x10EACAA: warn_uninitialized_phi(gphi*, vec<gphi*, va_heap, vl_ptr>*, hash_set<gphi*, default_hash_traits<gphi*> >*) (tree-ssa-uninit.c:2504)
==7340==    by 0x10EB1B3: (anonymous namespace)::pass_late_warn_uninitialized::execute(function*) (tree-ssa-uninit.c:2612)
==7340==    by 0xD36EB2: execute_one_pass(opt_pass*) (passes.c:2370)
Comment 5 Aldy Hernandez 2016-11-29 12:02:56 UTC
Looks like a P1 to me.  Mine.
Comment 6 Aldy Hernandez 2016-12-01 10:02:07 UTC
Among other things, the main problem here is that we save all the pred_chains from preds[] into s_preds[], then we free all said pred_chains with destroy_predicate_vecs(), but still keep a copy of the pred_chains in s_preds, which we later try to free from normalize_preds():

  /* Now clean up the chain.  */
  if (simplified)
    {
      for (i = 0; i < n; i++)
	{
	  if ((*preds)[i].is_empty ())
	    continue;
	  s_preds.safe_push ((*preds)[i]);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Makes a copy of the pred_chain.
	}

      destroy_predicate_vecs (preds);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// free() all the pred_chain's.
      (*preds) = s_preds;
// ^^^^^^^^^^^^^^^^^^^^^^
// Wait a minute, we still keep a copy of the pred_chains.
      s_preds = vNULL;
    }

I have no idea how this worked even before my patch.

I'm testing a fix.
Comment 7 Aldy Hernandez 2016-12-05 17:07:05 UTC
The following patch has been approved to fix this:

https://gcc.gnu.org/ml/gcc-patches/2016-12/msg00039.html

But it depends on the approval pending patch for pr78566.
Comment 8 Aldy Hernandez 2016-12-06 10:36:08 UTC
Author: aldyh
Date: Tue Dec  6 10:35:37 2016
New Revision: 243289

URL: https://gcc.gnu.org/viewcvs?rev=243289&root=gcc&view=rev
Log:
	PR middle-end/78548
	* tree-ssa-uninit.c (simplify_preds_4): Call release() instead of
	destroy_predicate_vecs.
	(uninit_uses_cannot_happen): Make uninit_preds a scalar.

Added:
    trunk/gcc/testsuite/gcc.dg/uninit-pr78548.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/tree-ssa-uninit.c
Comment 9 Aldy Hernandez 2016-12-06 10:38:03 UTC
Fixed.