Re: [PATCH][C++] Deal with non-sign-extended unsigned sizetype for arrays of size zero

2012-03-28 Thread Jason Merrill

OK.

Jason


[PATCH][C++] Deal with non-sign-extended unsigned sizetype for arrays of size zero

2012-03-28 Thread Richard Guenther

For arrays of size zero the C++ frontend generates a TYPE_DOMAIN
using build_index_type (which is hardcoded to unsigned sizetype)
passing it -1 (in ssizetype ...) as the maximum index (build_index_type
will use size_zero_node as minimum index).  That works all well
as long as sizetype constants are signextended, but
process_init_constructor_array does:

tree domain = TYPE_DOMAIN (type);
if (domain)
!   len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain))
! - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain))
! + 1);

so if that -1 is not sign-extended and sizetype is 32bits on a 64bit
host (where TREE_INT_CST_LOW is 64bit) then the above computes
a non-sensical value, 0x1, that is.  The C frontend (now)
avoids this by using a [0, ] TYPE_DOMAIN for the extension of
zero-size arrays but I see that size can be the result of template
expansion in C++ (and maybe other places in the C++ frontend assume
taht TYPE_MAX_VALUE of TYPE_DOMAIN is never NULL).  I know that
simply using a range type with ssizetype does not work (yeah, we
should make that work I guess ...), so the fix for the above code
is to properly do twos-complement arithmetic and truncate/extend
the HOST_WIDE_INT value.  Another fix would be to use a [1, 0]
domain - not sure what that would break though.

Like with the following patch (heh, C++ operator overloading would
make dealing with double-ints so much nicer to look at ...).

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

This cures the last non-Ada failure I have with the patchset that
makes TYPE_UNSIGNED sizetype constants no longer sign-extended.

Ok for trunk?

Thanks,
Richard.

2012-03-28  Richard Guenther  

cp/
* typeck2.c (process_init_constructor_array): Use the proper
type for computing the array length.

Index: gcc/cp/typeck2.c
===
*** gcc/cp/typeck2.c(revision 185911)
--- gcc/cp/typeck2.c(working copy)
*** process_init_constructor_array (tree typ
*** 1054,1062 
  {
tree domain = TYPE_DOMAIN (type);
if (domain)
!   len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain))
! - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain))
! + 1);
else
unbounded = true;  /* Take as many as there are.  */
  }
--- 1054,1067 
  {
tree domain = TYPE_DOMAIN (type);
if (domain)
!   len = double_int_ext
!   (double_int_add
! (double_int_sub
!   (tree_to_double_int (TYPE_MAX_VALUE (domain)),
!tree_to_double_int (TYPE_MIN_VALUE (domain))),
!   double_int_one),
! TYPE_PRECISION (TREE_TYPE (domain)),
! TYPE_UNSIGNED (TREE_TYPE (domain))).low;
else
unbounded = true;  /* Take as many as there are.  */
  }