re PR rtl-optimization/6713 (Regression wrt 3.0.4: g++ -O2 leads to seg fault at run time)

PR optimization/6713
 * loop.c (loop_givs_rescan): Explicitly delete the insn that
 sets a non-replaceable giv after issuing the new one.

Co-Authored-By: Glen Nakamura <glen@imodulo.com>

From-SVN: r55539
This commit is contained in:
Eric Botcazou 2002-07-17 18:00:35 +00:00 committed by Richard Henderson
parent 9088828378
commit f1a73cfecf
3 changed files with 135 additions and 2 deletions

View File

@ -1,3 +1,10 @@
2002-06-17 Eric Botcazou <ebotcazou@multimania.com>
Glen Nakamura <glen@imodulo.com>
PR optimization/6713
* loop.c (loop_givs_rescan): Explicitly delete the insn that
sets a non-replaceable giv after issuing the new one.
2002-07-17 Neil Booth <neil@daikokuya.co.uk>
* cppexp.c (cpp_interpret_integer, append_digit, parse_defined,

View File

@ -4874,10 +4874,20 @@ loop_givs_rescan (loop, bl, reg_map)
}
else
{
rtx original_insn = v->insn;
/* Not replaceable; emit an insn to set the original giv reg from
the reduced giv, same as above. */
loop_insn_emit_after (loop, 0, v->insn,
gen_move_insn (v->dest_reg, v->new_reg));
v->insn = loop_insn_emit_after (loop, 0, original_insn,
gen_move_insn (v->dest_reg,
v->new_reg));
/* The original insn may have a REG_EQUAL note. This note is
now incorrect and may result in invalid substitutions later.
We could just delete the note, but we know that the entire
insn is dead, so we might as well save ourselves the bother
and remove the whole thing. */
delete_insn (original_insn);
}
/* When a loop is reversed, givs which depend on the reversed

View File

@ -0,0 +1,116 @@
// PR optimization/6713
// This testcase segfaulted on x86 because a dangling REG_EQUAL note
// resulted in incorrect substitutions later.
// { dg-do run }
// { dg-options "-O2" }
template<typename _CharT> class basic_iterator
{
public:
basic_iterator(_CharT* _p) : _M_current(_p) {}
basic_iterator& operator++() { ++_M_current; return *this; }
_CharT& operator*() const { return *_M_current; }
bool operator!=(basic_iterator &_rhs) { return _M_current != _rhs._M_current; }
private:
_CharT* _M_current;
};
template<typename _CharT> class basic_string
{
public:
typedef unsigned int size_type;
typedef basic_iterator<_CharT> iterator;
private:
struct _Rep
{
size_type _M_length;
size_type _M_capacity;
int _M_references;
bool _M_is_leaked() const { return _M_references < 0; }
bool _M_is_shared() const { return _M_references > 0; }
void _M_set_leaked() { _M_references = -1; }
void _M_set_sharable() { _M_references = 0; }
};
struct _Rep _M_rep;
struct _Alloc_hider
{
_CharT _raw[16];
_CharT* _M_p;
};
mutable _Alloc_hider _M_dataplus;
_CharT* _M_data() const { return _M_dataplus._M_p; }
void _M_leak() { if (!_M_rep._M_is_leaked()) _M_leak_hard(); }
static int count;
static void _M_leak_hard();
public:
explicit basic_string(const _CharT* __s);
iterator begin() { _M_leak(); return iterator(_M_data()); }
iterator end() { _M_leak(); return iterator(_M_data() + this->size()); }
size_type size() const { return _M_rep._M_length; }
};
template<typename _CharT> basic_string<_CharT>::
basic_string(const _CharT* __s)
{
int i;
for (i=0; i<15; i++) {
if (!__s[i])
break;
_M_dataplus._raw[i] = __s[i];
}
_M_dataplus._raw[i] = 0;
_M_dataplus._M_p = _M_dataplus._raw;
_M_rep._M_length = i;
_M_rep._M_capacity = i;
_M_rep._M_references = 1;
}
template<typename _CharT> int basic_string<_CharT>::count = 0;
template<typename _CharT> void basic_string<_CharT>::
_M_leak_hard()
{
count++;
}
typedef basic_string<char> string;
int isspa(int ch)
{
return 0;
}
void foo(string& str)
{
string::iterator it = str.begin();
string::iterator stop = str.end();
for (; it != stop; ++it)
if (isspa(*it))
break;
}
int main()
{
string str("test");
foo(str);
}