This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix PR debug/59350
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 06 Jan 2014 12:37:06 +0100
- Subject: Fix PR debug/59350
- Authentication-results: sourceware.org; auth=none
This is the ICE on the checking assertion for ONEPART_VALUEs at the beginning
of vt_expand_var_loc_chain. The assertion looks a bit overzealous to me: it
triggers here because we don't record a SET in add_stores, but only because we
don't preserve the source: the source is a zero-extension of something and
cselib manages to record an equivalence between the value of this something
and the truncation of the value of the source(!) by the mere virtue of the
existence of the source (see cselib.c:2013 and below). Not sure why we would
need to preserve it if we don't use it, but that's very likely simpler.
Tested on x86_64-suse-linux, applied on the mainline as obvious.
2014-01-06 Eric Botcazou <ebotcazou@adacore.com>
PR debug/59350
PR debug/59510
* var-tracking.c (add_stores): Preserve the value of the source even if
we don't record the store.
2014-01-06 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/pr59350-2.c: New test.
* g++.dg/pr59510.C: Likewise.
--
Eric Botcazou
Index: var-tracking.c
===================================================================
--- var-tracking.c (revision 206336)
+++ var-tracking.c (working copy)
@@ -5930,6 +5930,13 @@ add_stores (rtx loc, const_rtx expr, voi
if (type != MO_VAL_SET)
goto log_and_return;
+ v = find_use_val (oloc, mode, cui);
+
+ if (!v)
+ goto log_and_return;
+
+ resolve = preserve = !cselib_preserved_value_p (v);
+
/* We cannot track values for multiple-part variables, so we track only
locations for tracked parameters passed either by invisible reference
or directly in multiple locations. */
@@ -5943,14 +5950,15 @@ add_stores (rtx loc, const_rtx expr, voi
&& XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) != arg_pointer_rtx)
|| (GET_CODE (DECL_INCOMING_RTL (REG_EXPR (loc))) == PARALLEL
&& XVECLEN (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) > 1)))
- goto log_and_return;
-
- v = find_use_val (oloc, mode, cui);
-
- if (!v)
- goto log_and_return;
-
- resolve = preserve = !cselib_preserved_value_p (v);
+ {
+ /* Although we don't use the value here, it could be used later by the
+ mere virtue of its existence as the operand of the reverse operation
+ that gave rise to it (typically extension/truncation). Make sure it
+ is preserved as required by vt_expand_var_loc_chain. */
+ if (preserve)
+ preserve_value (v);
+ goto log_and_return;
+ }
if (loc == stack_pointer_rtx
&& hard_frame_pointer_adjustment != -1
/* PR debug/59350 */
/* { dg-do compile } */
/* { dg-options "-O -g " } */
typedef struct
{
void *v;
int len;
int sign;
} ZVALUE;
extern int pred (ZVALUE);
static unsigned long
small_factor (ZVALUE z)
{
if (z.len > 0)
return 0;
return pred (z) ? -1 : 0;
}
unsigned long
zfactor (ZVALUE z)
{
z.sign = 0;
return small_factor (z);
}
// PR debug/59510
// { dg-do compile }
// { dg-options "-O2 -g --param=large-stack-frame-growth=1" }
template <typename _Iterator>
struct _Iter_base
{
typedef _Iterator iterator_type;
};
template <typename _CharT>
struct basic_ostream;
template <typename _CharT>
struct basic_ostringstream;
template <typename _CharT>
struct ostreambuf_iterator;
typedef basic_ostringstream <char>ostringstream;
template <typename _Iterator> struct _Miter_base : _Iter_base <_Iterator>
{
};
template <typename _Iterator>
typename _Miter_base <_Iterator>::iterator_type __miter_base (_Iterator);
template <typename _CharT>
ostreambuf_iterator <_CharT>
__copy_move_a2 (ostreambuf_iterator <_CharT>);
template <typename _II, typename _OI>
_OI copy (_II __first, _II __last, _OI __result)
{
__copy_move_a2 <false> (__first, __miter_base (__last), __result);
}
struct ios_base {
struct _Words {
int *_M_pword;
long _M_iword;
};
_Words _M_local_word[8];
};
template <typename _CharT>
struct basic_streambuf
{
typedef _CharT char_type;
int sputn (char_type *, int);
};
template <typename _CharT>
struct ostreambuf_iterator
{
typedef basic_streambuf <_CharT> streambuf_type;
typedef basic_ostream <_CharT> ostream_type;
streambuf_type *_M_sbuf;
bool _M_failed;
ostreambuf_iterator (ostream_type __s) : _M_sbuf (__s.rdbuf ()), _M_failed () {}
void _M_put (_CharT * __ws, int __len)
{
if (_M_failed && _M_sbuf->sputn (__ws, __len) != __len) _M_failed = true;
}
};
template <bool, typename _CharT>
void __copy_move_a2 (_CharT * __first,_CharT * __last,ostreambuf_iterator <_CharT> __result)
{
int __num = __last - __first;
__result._M_put (__first, __num);
}
template <typename _CharT>
struct basic_ios : ios_base
{
basic_streambuf <_CharT> *rdbuf ();
};
template <typename _CharT>
struct basic_ostream : public basic_ios <_CharT>
{
};
template <typename _CharT>
struct basic_ostringstream : public basic_ostream <_CharT>
{
};
void
test01 () {
char data1[] = "foo";
char *beg1 = data1;
ostringstream oss1;
ostreambuf_iterator <char> out1 (oss1);
out1 = copy (beg1, beg1, out1);
}