diff options
author | Richard Biener <rguenther@suse.de> | 2012-12-20 12:45:48 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-12-20 12:45:48 +0000 |
commit | 63f2ff0f23d633aad769997ec617ce2177c311ec (patch) | |
tree | be55ad20b58a1170be63f32e62e1407bc7395272 /gcc | |
parent | eadd3d0d54b72308446ce8e615b180fe33eed36a (diff) | |
download | gcc-63f2ff0f23d633aad769997ec617ce2177c311ec.zip gcc-63f2ff0f23d633aad769997ec617ce2177c311ec.tar.gz gcc-63f2ff0f23d633aad769997ec617ce2177c311ec.tar.bz2 |
re PR rtl-optimization/55740 (ICE in verify_loop_structure, at cfgloop.c:1582, error: loop 2's header does not belong directly to it)
2012-12-20 Richard Biener <rguenther@suse.de>
PR middle-end/55740
* cfghooks.c (merge_blocks): Properly handle merging of
two loop headers.
* g++.dg/torture/pr55740.C: New testcase.
From-SVN: r194633
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cfghooks.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr55740.C | 19 |
4 files changed, 45 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6d38560..01ed19b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-12-20 Richard Biener <rguenther@suse.de> + + PR middle-end/55740 + * cfghooks.c (merge_blocks): Properly handle merging of + two loop headers. + 2012-12-20 Roland Stigge <stigge@debian.org> Matthias Klose <doko@ubuntu.com> diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index f095731..b729ae0 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -724,11 +724,23 @@ merge_blocks (basic_block a, basic_block b) cfg_hooks->merge_blocks (a, b); - /* If we merge a loop header into its predecessor, update the loop - structure. */ if (current_loops != NULL) { - if (b->loop_father->header == b) + /* If the block we merge into is a loop header do nothing unless ... */ + if (a->loop_father->header == a) + { + /* ... we merge two loop headers, in which case we kill + the inner loop. */ + if (b->loop_father->header == b) + { + b->loop_father->header = NULL; + b->loop_father->latch = NULL; + loops_state_set (LOOPS_NEED_FIXUP); + } + } + /* If we merge a loop header into its predecessor, update the loop + structure. */ + else if (b->loop_father->header == b) { remove_bb_from_loops (a); add_bb_to_loop (a, b->loop_father); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1b7c851..1f401cd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-12-20 Richard Biener <rguenther@suse.de> + + PR middle-end/55740 + * g++.dg/torture/pr55740.C: New testcase. + 2012-12-20 Jakub Jelinek <jakub@redhat.com> PR c++/55619 diff --git a/gcc/testsuite/g++.dg/torture/pr55740.C b/gcc/testsuite/g++.dg/torture/pr55740.C new file mode 100644 index 0000000..cdd8425 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr55740.C @@ -0,0 +1,19 @@ +// { dg-do compile } + +static bool st_IsPathDelimiter( char c ) { return c == '/'; } +bool IsValidPath( char const * filename ) +{ + if ( !filename || filename[0] == 0 ) + return false; + char const * run = filename; + while ( run && *run ) + { + if ( run[0] == '.' ) + if ( run[1] != '.' || ( !st_IsPathDelimiter( run[2] ) && run[2] != 0 ) ) + return false; + while ( *run && !st_IsPathDelimiter( *run ) ) + ++run; + if ( *run ) + ++run; + } +} |