This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Do not use lang_hooks.types.type_for_size in signed_or_unsigned_type_for
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 7 Mar 2012 13:22:57 +0100 (CET)
- Subject: [PATCH] Do not use lang_hooks.types.type_for_size in signed_or_unsigned_type_for
This makes us use build_nonstandard_integer_type in
signed_or_unsigned_type_for and adjusts the function to return
NULL_TREE for non-sensical inputs (only allowing pointer and
integeral types). This way we make sure that the precision of
the result type matches that of the input - something which
fold-const.c definitely expects for example (it uses type_for_size
itself if it doesn't).
In the long run type_for_size should go - or it should be a
wrapper that calls type_for_mode (int_mode_for_size ()) instead.
I'm working towards that.
Bootstrapped and tested on x86_64-unknown-linux-gnu for all languages.
I get
FAIL: gcc.dg/tree-ssa/pr31261.c scan-tree-dump-times original "return
\\(char\\)
-\\(unsigned char\\) c & 31;" 1
FAIL: gcc.dg/tree-ssa/pr31261.c scan-tree-dump-times original "return
\\(int\\)
\\(12 - \\(unsigned int\\) d\\) & 7;" 1
because we dump the unsigned type variant differently now. What do
people think - adjust the testcase? Adjust how we pretty-print
these non-standard integer types?
Thanks,
Richard.
2012-03-07 Richard Guenther <rguenther@suse.de>
* tree.c (signed_or_unsigned_type_for): Use
build_nonstandard_integer_type.
(signed_type_for): Adjust documentation.
(unsigned_type_for): Likewise.
Index: gcc/tree.c
===================================================================
*** gcc/tree.c (revision 185029)
--- gcc/tree.c (working copy)
*************** widest_int_cst_value (const_tree x)
*** 10197,10228 ****
return val;
}
! /* If TYPE is an integral type, return an equivalent type which is
! unsigned iff UNSIGNEDP is true. If TYPE is not an integral type,
! return TYPE itself. */
tree
signed_or_unsigned_type_for (int unsignedp, tree type)
{
! tree t = type;
! if (POINTER_TYPE_P (type))
! {
! /* If the pointer points to the normal address space, use the
! size_type_node. Otherwise use an appropriate size for the pointer
! based on the named address space it points to. */
! if (!TYPE_ADDR_SPACE (TREE_TYPE (t)))
! t = size_type_node;
! else
! return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp);
! }
! if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp)
! return t;
! return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp);
}
! /* Returns unsigned variant of TYPE. */
tree
unsigned_type_for (tree type)
--- 10197,10222 ----
return val;
}
! /* If TYPE is an integral or pointer type, return an integer type with
! the same precision which is unsigned iff UNSIGNEDP is true, or itself
! if TYPE is already an integer type of signedness UNSIGNEDP. */
tree
signed_or_unsigned_type_for (int unsignedp, tree type)
{
! if (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type) == unsignedp)
! return type;
! if (!INTEGRAL_TYPE_P (type)
! && !POINTER_TYPE_P (type))
! return NULL_TREE;
! return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
}
! /* If TYPE is an integral or pointer type, return an integer type with
! the same precision which is unsigned, or itself if TYPE is already an
! unsigned integer type. */
tree
unsigned_type_for (tree type)
*************** unsigned_type_for (tree type)
*** 10230,10236 ****
return signed_or_unsigned_type_for (1, type);
}
! /* Returns signed variant of TYPE. */
tree
signed_type_for (tree type)
--- 10224,10232 ----
return signed_or_unsigned_type_for (1, type);
}
! /* If TYPE is an integral or pointer type, return an integer type with
! the same precision which is signed, or itself if TYPE is already a
! signed integer type. */
tree
signed_type_for (tree type)