re PR middle-end/59119 (Segfault in -fisolate-erroneous-paths pass)
* PR middle-end/59119 * gimple-ssa-isolate-paths.c (find_implicit_erroneous_behaviour): New function, extracted from gimple_ssa_isolate_erroneous_paths. (find_explicit_erroneous_behaviour): Similarly. (insert_trap_and_remove_trailing_statements): Remove statements in reverse order. * PR middle-end/59119 * gcc.c-torture/compile/pr59119.c: New test. From-SVN: r204760
This commit is contained in:
parent
98eaa66fa5
commit
56d338c931
4 changed files with 118 additions and 35 deletions
|
@ -1,3 +1,12 @@
|
|||
2013-11-13 Jeff Law <law@redhat.com>
|
||||
|
||||
* PR middle-end/59119
|
||||
* gimple-ssa-isolate-paths.c (find_implicit_erroneous_behaviour): New
|
||||
function, extracted from gimple_ssa_isolate_erroneous_paths.
|
||||
(find_explicit_erroneous_behaviour): Similarly.
|
||||
(insert_trap_and_remove_trailing_statements): Remove statements
|
||||
in reverse order.
|
||||
|
||||
2013-11-13 Steven Bosscher <steven@gcc.gnu.org>
|
||||
|
||||
* cfgrtl.c (can_fallthru): Reorder code to move tablejump check up.
|
||||
|
|
|
@ -100,14 +100,16 @@ insert_trap_and_remove_trailing_statements (gimple_stmt_iterator *si_p, tree op)
|
|||
else
|
||||
gsi_insert_before (si_p, seq, GSI_NEW_STMT);
|
||||
|
||||
/* The iterator points to the __builtin_trap. Advance the iterator
|
||||
and delete everything else in the block. */
|
||||
gsi_next (si_p);
|
||||
for (; !gsi_end_p (*si_p);)
|
||||
/* We must remove statements from the end of the block so that we
|
||||
never reference a released SSA_NAME. */
|
||||
basic_block bb = gimple_bb (gsi_stmt (*si_p));
|
||||
for (gimple_stmt_iterator si = gsi_last_bb (bb);
|
||||
gsi_stmt (si) != gsi_stmt (*si_p);
|
||||
si = gsi_last_bb (bb))
|
||||
{
|
||||
stmt = gsi_stmt (*si_p);
|
||||
stmt = gsi_stmt (si);
|
||||
unlink_stmt_vdef (stmt);
|
||||
gsi_remove (si_p, true);
|
||||
gsi_remove (&si, true);
|
||||
release_defs (stmt);
|
||||
}
|
||||
}
|
||||
|
@ -192,40 +194,19 @@ isolate_path (basic_block bb, basic_block duplicate,
|
|||
return duplicate;
|
||||
}
|
||||
|
||||
/* Search the function for statements which, if executed, would cause
|
||||
the program to fault such as a dereference of a NULL pointer.
|
||||
/* Look for PHI nodes which feed statements in the same block where
|
||||
the value of the PHI node implies the statement is erroneous.
|
||||
|
||||
Such a program can't be valid if such a statement was to execute
|
||||
according to ISO standards.
|
||||
For example, a NULL PHI arg value which then feeds a pointer
|
||||
dereference.
|
||||
|
||||
We detect explicit NULL pointer dereferences as well as those implied
|
||||
by a PHI argument having a NULL value which unconditionally flows into
|
||||
a dereference in the same block as the PHI.
|
||||
|
||||
In the former case we replace the offending statement with an
|
||||
unconditional trap and eliminate the outgoing edges from the statement's
|
||||
basic block. This may expose secondary optimization opportunities.
|
||||
|
||||
In the latter case, we isolate the path(s) with the NULL PHI
|
||||
feeding the dereference. We can then replace the offending statement
|
||||
and eliminate the outgoing edges in the duplicate. Again, this may
|
||||
expose secondary optimization opportunities.
|
||||
|
||||
A warning for both cases may be advisable as well.
|
||||
|
||||
Other statically detectable violations of the ISO standard could be
|
||||
handled in a similar way, such as out-of-bounds array indexing. */
|
||||
|
||||
static unsigned int
|
||||
gimple_ssa_isolate_erroneous_paths (void)
|
||||
When found isolate and optimize the path associated with the PHI
|
||||
argument feeding the erroneous statement. */
|
||||
static void
|
||||
find_implicit_erroneous_behaviour (void)
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
initialize_original_copy_tables ();
|
||||
|
||||
/* Search all the blocks for edges which, if traversed, will
|
||||
result in undefined behaviour. */
|
||||
cfg_altered = false;
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
gimple_stmt_iterator si;
|
||||
|
@ -288,6 +269,21 @@ gimple_ssa_isolate_erroneous_paths (void)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for statements which exhibit erroneous behaviour. For example
|
||||
a NULL pointer dereference.
|
||||
|
||||
When found, optimize the block containing the erroneous behaviour. */
|
||||
static void
|
||||
find_explicit_erroneous_behaviour (void)
|
||||
{
|
||||
basic_block bb;
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
gimple_stmt_iterator si;
|
||||
|
||||
/* Now look at the statements in the block and see if any of
|
||||
them explicitly dereference a NULL pointer. This happens
|
||||
|
@ -318,6 +314,56 @@ gimple_ssa_isolate_erroneous_paths (void)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Search the function for statements which, if executed, would cause
|
||||
the program to fault such as a dereference of a NULL pointer.
|
||||
|
||||
Such a program can't be valid if such a statement was to execute
|
||||
according to ISO standards.
|
||||
|
||||
We detect explicit NULL pointer dereferences as well as those implied
|
||||
by a PHI argument having a NULL value which unconditionally flows into
|
||||
a dereference in the same block as the PHI.
|
||||
|
||||
In the former case we replace the offending statement with an
|
||||
unconditional trap and eliminate the outgoing edges from the statement's
|
||||
basic block. This may expose secondary optimization opportunities.
|
||||
|
||||
In the latter case, we isolate the path(s) with the NULL PHI
|
||||
feeding the dereference. We can then replace the offending statement
|
||||
and eliminate the outgoing edges in the duplicate. Again, this may
|
||||
expose secondary optimization opportunities.
|
||||
|
||||
A warning for both cases may be advisable as well.
|
||||
|
||||
Other statically detectable violations of the ISO standard could be
|
||||
handled in a similar way, such as out-of-bounds array indexing. */
|
||||
|
||||
static unsigned int
|
||||
gimple_ssa_isolate_erroneous_paths (void)
|
||||
{
|
||||
initialize_original_copy_tables ();
|
||||
|
||||
/* Search all the blocks for edges which, if traversed, will
|
||||
result in undefined behaviour. */
|
||||
cfg_altered = false;
|
||||
|
||||
/* First handle cases where traversal of a particular edge
|
||||
triggers undefined behaviour. These cases require creating
|
||||
duplicate blocks and thus new SSA_NAMEs.
|
||||
|
||||
We want that process complete prior to the phase where we start
|
||||
removing edges from the CFG. Edge removal may ultimately result in
|
||||
removal of PHI nodes and thus releasing SSA_NAMEs back to the
|
||||
name manager.
|
||||
|
||||
If the two processes run in parallel we could release an SSA_NAME
|
||||
back to the manager but we could still have dangling references
|
||||
to the released SSA_NAME in unreachable blocks.
|
||||
that any released names not have dangling references in the IL. */
|
||||
find_implicit_erroneous_behaviour ();
|
||||
find_explicit_erroneous_behaviour ();
|
||||
|
||||
free_original_copy_tables ();
|
||||
|
||||
/* We scramble the CFG and loop structures a bit, clean up
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2013-11-12 Jeff Law <law@redhat.com>
|
||||
|
||||
* PR middle-end/59119
|
||||
* gcc.c-torture/compile/pr59119.c: New test.
|
||||
|
||||
2013-11-13 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* gcc.dg/ira-shrinkwrap-prep-1.c: Add lp64 to target requirements.
|
||||
|
|
23
gcc/testsuite/gcc.c-torture/compile/pr59119.c
Normal file
23
gcc/testsuite/gcc.c-torture/compile/pr59119.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
extern void *memmove (void *, const void *, __SIZE_TYPE__);
|
||||
extern void *memset (void *, int, __SIZE_TYPE__);
|
||||
|
||||
typedef struct {
|
||||
long n_prefix;
|
||||
long n_spadding;
|
||||
} NumberFieldWidths;
|
||||
|
||||
void
|
||||
fill_number(char *buf, const NumberFieldWidths *spec)
|
||||
{
|
||||
if (spec->n_prefix) {
|
||||
memmove(buf,
|
||||
(char *) 0,
|
||||
spec->n_prefix * sizeof(char));
|
||||
buf += spec->n_prefix;
|
||||
}
|
||||
if (spec->n_spadding) {
|
||||
memset(buf, 0, spec->n_spadding);
|
||||
buf += spec->n_spadding;
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue