This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR debug/59350


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);
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]