This is the mail archive of the gcc@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]

Your sizetype changes ...



... broke this test-case:

  struct Base_bitset {
    unsigned M_w[2];
    void M_do_right_shift();
  };

  void Base_bitset::M_do_right_shift ()
  {
    unsigned n = 0;
    M_w[0] =  M_w[n + 1]  ;
  }

in C++, on (at least) x86-linux-gnu.

The underlying reason is that the C++ front-end contains this code, in
ocp_convert:

      if (same_type_p (type, TREE_TYPE (e)))
	return e;

which says that if `e' is of the same type as `type', then you don't
need to do any conversion; just return `e'.

Now that breaks if TYPE_IS_SIZETYPE holds for `type', but not for
`TREE_TYPE (e)'.

The notion of "same type" is a language-specific one, and in C++, like
C, `unsigned int' and `size_t' are often the same type.  It's fine for
GCC to use different nodes to represent them, but they had better be
treated the same, only when parsing, but also when optimizing.
*Anything* that is legal to do with a size_t is also legal to do with
an unsigned int, and vice versa.  So, this comment:

  /* In an INTEGER_TYPE, it means the type represents a size.  We use this
     both for validity checking and to permit optimziations that are unsafe
     for other types.  */
  #define TYPE_IS_SIZETYPE(NODE) (TYPE_CHECK (NODE)->type.no_force_blk_flag)

is somewhat misleading.  The only time any such optimization would be
safe is if you knew that it was actually the DECL_SIZE/TYPE_SIZE/etc
of something; not just because it's a `size_t'.  Is that what you
meant?  How do you propose to keep track of that fact across code
like:
  
  ((size_t) (sizeof (x) - 1))

In any case, there's no reason to change the behavior of the C++
front-end.  For instance, adding a NOP_EXPR to convert to a type with
TYPE_IS_SIZETYPE set would be silly; it's semantically meaningless to
the front-end, and the back-end can't make use of the information for
any optimization since, say, a cast to `size_t' doesn't make for any
different properties of the underlying expression.

Perhaps something in the middle-end should change to convert these
things to size_t before calling size_binop/size_diffop.  I don't
really see why, but that sounds vaguely plausible.  For now, I'm
checking the attached to 

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2000-02-29  Mark Mitchell  <mark@codesourcery.com>

	* fold-const.c (size_binop): Don't asert inputs are the same
	and have TYPE_IS_SIZETYPE set.
	(size_diffop): Likewise.

Index: testsuite/g++.old-deja/g++.other/crash13.C
===================================================================
RCS file: crash13.C
diff -N crash13.C
*** /dev/null	Tue May  5 13:32:27 1998
--- crash13.C	Tue Feb 29 15:54:15 2000
***************
*** 0 ****
--- 1,11 ----
+ struct Base_bitset {
+   unsigned M_w[2];
+   void M_do_right_shift();
+ };
+ 
+ 
+ void Base_bitset::M_do_right_shift ()
+ {
+   unsigned n = 0;
+   M_w[0] =  M_w[n + 1]  ;
+ }

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